C# DotNetZip auf MacOS

CrazyIwan

Lt. Commander
Registriert
Apr. 2007
Beiträge
1.302
Hallo allerseits,

ich habe hier ein Problem mit DotNetZip unter MacOS. Ich habe eine .app gezipped und entpacke diese mit der lib. Alles funktioniert und die Datei mit Unterordnern werden richtig unzipped. Dennoch kann ich die Anwendung, sprich .app, nicht ausführen. Die startet einfach nicht.
Am zip liegt es nicht, denn wenn ich es mit MacOS entpacke läuft alles.

Hat wer eine Idee bzw. hat wer mit DotNetZip unter Mac Erfahrungen?

Anbei der Unzip-Funktion
Code:
void Unzip ()
{
	try
        {
		using (ZipFile zf = ZipFile.Read ("update.zip")) 
               {
				
			foreach (ZipEntry zEntry in zf) 
                       {
				if (!zEntry.FileName.StartsWith ("__")) 
                                {
					zEntry.OpenReader ();
					zEntry.Extract (
                                             Directory.GetCurrentDirectory () + "/tmp",
                                             ExtractExistingFileAction.OverwriteSilently);
				}

			}
			zf.Dispose ();
		}
	} catch (System.Exception ex) {
		Debug.Log (ex);
		StartGame ();
	}
	finally
	{
		DeleteTemp ();
	}
}
 
Dot NET? Du meinst MS .NET?

Wenn es so ist, kannst du es vergessen ohne entsprechende vorkehrungen zu treffen dort dein Programm zu installieren! Hast du vielleicht Mono auf dem MAC oder sowas ähnliches dass die geschriebenen DLL entsprechend übersetzen kann?
 
Benutze Unity Pro mit Mono. DotNetZip ist eine ZIP Library die ich statt MS ZipStream benutze. Es funktioniert auch alles wunderbar, bis eben auf die Tatsache, dass die entpackte .app nicht mehr ausführen möchte.
 
was ist mit debuggen? Hast du da schon versucht? den Breakpoint zu setzen und dann auf den Event warten... halt button click oder was auch immer!
 
Debuggen bringt in dem Fall leider nicht viel. Es funktioniert ja auch eigentlich alles. Auf dem Mac kann man die .app aufmachen, als ein Art Ordner so zusagen. Und es ist alles in der entpackten Datei drinnen, was im Original ist. Nur will die nicht starten :D
 
Hm hast du dein Code genau studiert... ich habe leider erst jetzt bemerkt... du machst einen Dispose in der USING(){}... das könnte eventuell zu deinen Fehlerhaften Code führen. Ich glaube du hast den Sinn von USING nicht verstanden.

mach aus dem Using einen Try Catch. Im Catch Teil lasse deinen Fehler ausgeben, falls welcher passieren sollte. An sich ist Dispose nicht wirklich falsch (in deinem Using) aber wenn jetzt die Speicherfreigabe doch schnell genug arbeitet, so könnte es sein, das genau dort error passiert.

Mit Using hast du eigentlich doppelt gemoppelt... Using macht nichts anderes als try catch, wobei catch in diesem fall leer ist und dort nichts gemacht und, und finally auf dem object was du in der using eingebaut hast.

Using mache ich in meinem Code fast nie, da ich fehler immer versuche abzufangen anstatt diese zu schlucken.

hm also machs so....

Code:
void Unzip ()
{
        ZipFile zf  =null;
	try
        {
		zf = ZipFile.Read ("update.zip");
				
		foreach (ZipEntry zEntry in zf) 
		{
			if (!zEntry.FileName.StartsWith ("__")) 
			{
				zEntry.OpenReader ();
				zEntry.Extract (
					Directory.GetCurrentDirectory () + "/tmp",
                			ExtractExistingFileAction.OverwriteSilently);
			}
		}
	} catch (System.Exception ex) {
		Debug.Log (ex);
		StartGame ();
	}
	finally
	{
		if(zf!=null)
			zf.Dispose ();
		DeleteTemp ();
	}
}
 
Zuletzt bearbeitet:
@Roker:

dein Beispiel wird wahrscheinlich nicht mal kompilieren.

1. ZipFile zf = null; // 1. zf deklariert und mit null initialisiert
2. ZipFile zf = ZipFile.Read ("update.zip"); // 2. zf deklariert und mit ZipFile.Read ("update.zip") initialisiert

Ich denke das der Compiler das noch nicht einmal schlucken wird, da hier bei der 2. Zeile dann 2 lokale Variablen mit dem gleichen Namen existieren sollen.

@CrazyIvan: Wie roker schon bemerkte, machst du 2 Dispose() in deinem Code: Einmal explizit mit zf.Dispose() und einmal implizit durch die Verwendung von Using{} Das sollte jedoch kein Problem sein, da Dispose() auch mehrfach aufgerufen werden kann.

Du schreibst jedoch das die App nicht mehr startet, wenn du die App aber von Hand entpackst läuft es. Also mach mal folgendes, wenn du ein Compare Tool auf dem Mac zur Verfügung hast, dann vergleiche das Ergebnis des Entpackens, sprich die entpackte Version deiner App mit der Version die du von Hand entpackt hast. Gibt es da Unterschiede? Wenn nein dann liegt es sicher nicht an deinem Code.

Die andere Sache ist, das wenn mich nicht alles täuscht das Mac OS X seinen Ursprung aus der BSD/Unix Welt hat. Soweit ich weiss, gibt es da ein Executable Flag im Filesystem. Sonst ist es einfach nur eine Datei, die im Filesystem liegt. Vielleicht macht das das MacOS automatisch, wenn du die Datei von Hand entpackt hast, während dein Update Algorithmus das eben nicht macht. Kannst ja mal folgendes prüfen in dem du die Attribute im Dateisystem zwischen deiner App, entpackt über deinen Code, mit den Attribute der App, entpackt über MacOS, vergleichst. Schreib mal was das Ergebnis ist.

Viel Erfolg!

Rossibaer
 
hmm hab gerade kein Mono auf der Hand und die DotNetZip Lib auch nicht.

Normalerweise kann man die Klassen auch mit null initialisieren. Ja mit doppelten Dispose aufruf kenne ich, dass man es mehrmals aufrufen kann. Ich bin nicht pro und kann nur aus Erfahrung sagen, dass doppelter Dispose nicht immer funktioniert. Deswegen sollte man sowas immer vermeiden!

Also ist es wie bei MFC... das man explizit für jedes OS einen Eintrag machen muss? Ich dachte, dass Mono oder generell C# sowas nicht braucht!
 
Vielen Dank an euch beide, habe jetzt das Problem gelöst.

Es lag nicht am Code sondern an den Rechten auf dem MacOS. Der interner unzip von Mac vergibt anscheinend richtige Rechte, oder auch Flags wie Rossibaer es auch angemerkt hat, an jeweilige Startdateien. Dazu gehört die Datei die sich in der App unter /Content/MacOS/ befindet. Hat diese Datei kein "Ausführungsrecht", startet die Anwendung nicht.

Habe jetzt so das Problem umgegangen, dass ich in C# chmod Prozess aufrufe und die rechte nachträglich vergebe.

Danke noch mal :)
 
ist doch eigentlich auch logisch. Eine Datei muss eben executable gesetzt sein, um ausgeführt werden zu können.
 
Naja, eigentlich nicht ganz logisch, denn die im ZIP befindliche Datei ist schon als executable gesetzt. Ich verstehe nicht ganz warum der MacOS interner Unzip richtig entpackt, der DotNet aber nicht. Aber über den Workaround funktioniert ja schließlich doch.
 
Zurück
Oben