Benutzer mit den meisten Antworten
Datei aus Anwendung entpacken

Frage
-
Antworten
-
Hallo K.,
Szenario A:
Mal angenommen, Du hast die Datei Settings.exe über [Projekt > Eigenschaften > Ressourcen > Ressource hinzufügen > Vorhandene Datei hinzufügen...] als Ressource hinzugefügt. Nach erfolgtem Import heißt deine Ressource nun Settings.
So extrahierst Du die Datei aus den Ressourcen (einfache Version):string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "settings.exe");
byte[] fileBytes = Properties.Resources.Settings;
File.WriteAllBytes(fileName, fileBytes);
Wenn Du die Neugier hast, zu sehen, was dahintersteckt, kannst Du nach Import der Ressource die Datei Resources.Designer.cs im Editor öffnen und dir die Property Settings ansehen. Du wirst merken, dass hier eine Klasse namens ResourceManager verwendet wird (auf die ich bereits im ersten Posting hingewiesen habe). Über den Aufruf ResourceManager.GetObject("Settings", resourceCulture) wird ein Objekt zurückgegeben, das anschließend in ein byte[]-Array umgewandelt wird.Aber der Zugriff auf die Ressource kann auch low-level und entsprechend performant (wenn z.B. mehrere Resourcen gleichzeitig extrahiert werden sollen) gestaltet werden:
Assembly executingAssembly = this.GetType().Assembly;
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Settings.exe");string exeFileResourceName = "Settings";
string applicationNamespace = "WindowsFormsApplication1";
string propertiesNamespace = String.Format("{0}.Properties", applicationNamespace);
string resourcesNamespace = String.Format("{0}.Resources", propertiesNamespace);
string resgenExtension = "resources";
string completeResourceName = String.Format("{0}.{1}", resourcesNamespace, resgenExtension);
using (Stream resourceStream = executingAssembly.GetManifestResourceStream(completeResourceName)) {
if(resourceStream != null) {
ResourceReader reader = new ResourceReader(resourceStream);
foreach (DictionaryEntry entry in reader) {
if (entry.Key.ToString() == exeFileResourceName) {
byte[] fileBytes = (byte[])entry.Value;
File.WriteAllBytes(fileName, fileBytes);
}
}
}
}
Wie Du siehst, muss der Ressourcenname aus mehreren Informationsteilen zusammengestellt werden (nochmals: s. Chris Sells Artikel oben). Der Ressourcen-Strom wird anschließend an einen ResourceReader weitergegeben, der die DictionaryEntry-Einträge durchsucht, den richtigen findet und das Byte-Array letztendlich auf die Festplatte speichert.
Szenario B (s. Link in Stefans Posting):
Wenn Du hingegen die ausführbare Datei über Projekt > Vorhandenes Element hinzufügen in dein Projekt eingefügt hast (und im Eigenschaftenfenster als Buildvorgang 'Eingebettete Ressource' ausgewählt hast!), kann die Ressource über einen voll qualifizierten Namen angesprochen werden, der sich wie folgt zusammensetzt:
[Standardnamespace].[Relativer Projektpfad].[DateiName]D.h. wenn dein Standardnamespace (Projekt > Eigenschaften > Anwendung) z.B. WindowsFormsApplication1 lautet und Du die Datei im Projektordner EXE gespeichert hast, würde der Ressourcenname so aussehen:
WindowsFormsApplication1.EXE.Settings.exeUnd falls die ausführbare Datei im Projekt-Stammordner residiert:
WindowsFormsApplication1.Settings.exe
Gruß
Marcel- Bearbeitet Marcel RomaModerator Mittwoch, 7. Dezember 2011 11:25 Text verschoben
- Als Antwort markiert KK Senior Mittwoch, 7. Dezember 2011 18:38
-
Hi,
wenn Du auch noch sagen würdest, wo Du diese Datei wie in deiner Anwendung vorliegen hast, könnte man dir evtl. auch helfen.
Falls das auch Teil deiner Frage ist: Man kann auch Dateien als Resource in die Anwendung packen und diese dann bspw. per
System.IO.File....
ins Dateisystem schreiben. Siehe dazu bspw.:
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort vorgeschlagen Marcel RomaModerator Mittwoch, 7. Dezember 2011 17:40
- Als Antwort markiert KK Senior Mittwoch, 7. Dezember 2011 18:38
-
Hallo K.,
Du könntest die gewünschte Datei einfach als Resource in deine Anwendung packen (wie Stefan das bereits vorschlug!). Da Resourcen in den Metadaten der Assembly eingebettet sind, kann man sehr einfach auf sie zugreifen. Die zwei gebräuchlichsten Modi sind der direkte Zugriff über Stream und der Zugriff über den ResourceManager. Bei Dateien ist meist der Streamzugriff gebräuchlich, da etwas performanter.
GetManifestResourceStream:
http://msdn.microsoft.com/de-de/library/xc4235zt(v=VS.100).aspx
ResourceManager:
http://msdn.microsoft.com/de-de/library/system.resources.resourcemanager.aspxRalph Westphal - Single Assembly Deployment of Managed and Unmanaged Code (Codebeispiel):
http://weblogs.asp.net/ralfw/archive/2007/02/04/single-assembly-deployment-of-managed-and-unmanaged-code.aspx
Chris Sells - Microsoft .NET Framework Resource Basics:
http://msdn.microsoft.com/de-de/library/ms950960.aspxGruß
Marcel- Bearbeitet Marcel RomaModerator Dienstag, 6. Dezember 2011 08:54 Hinweis auf Stefans Posting
- Als Antwort markiert KK Senior Mittwoch, 7. Dezember 2011 16:55
Alle Antworten
-
Hi,
wenn Du auch noch sagen würdest, wo Du diese Datei wie in deiner Anwendung vorliegen hast, könnte man dir evtl. auch helfen.
Falls das auch Teil deiner Frage ist: Man kann auch Dateien als Resource in die Anwendung packen und diese dann bspw. per
System.IO.File....
ins Dateisystem schreiben. Siehe dazu bspw.:
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort vorgeschlagen Marcel RomaModerator Mittwoch, 7. Dezember 2011 17:40
- Als Antwort markiert KK Senior Mittwoch, 7. Dezember 2011 18:38
-
Hallo K.,
Du könntest die gewünschte Datei einfach als Resource in deine Anwendung packen (wie Stefan das bereits vorschlug!). Da Resourcen in den Metadaten der Assembly eingebettet sind, kann man sehr einfach auf sie zugreifen. Die zwei gebräuchlichsten Modi sind der direkte Zugriff über Stream und der Zugriff über den ResourceManager. Bei Dateien ist meist der Streamzugriff gebräuchlich, da etwas performanter.
GetManifestResourceStream:
http://msdn.microsoft.com/de-de/library/xc4235zt(v=VS.100).aspx
ResourceManager:
http://msdn.microsoft.com/de-de/library/system.resources.resourcemanager.aspxRalph Westphal - Single Assembly Deployment of Managed and Unmanaged Code (Codebeispiel):
http://weblogs.asp.net/ralfw/archive/2007/02/04/single-assembly-deployment-of-managed-and-unmanaged-code.aspx
Chris Sells - Microsoft .NET Framework Resource Basics:
http://msdn.microsoft.com/de-de/library/ms950960.aspxGruß
Marcel- Bearbeitet Marcel RomaModerator Dienstag, 6. Dezember 2011 08:54 Hinweis auf Stefans Posting
- Als Antwort markiert KK Senior Mittwoch, 7. Dezember 2011 16:55
-
Hallo Marcel,
nur aus Interesse: Wo ist jetzt der große Unterschied zu dem, was ich geschrieben habe?
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert KK Senior Mittwoch, 7. Dezember 2011 17:05
- Tag als Antwort aufgehoben Marcel RomaModerator Mittwoch, 7. Dezember 2011 17:39
-
Hallo Stefan,
Die Gemeinsamkeiten überwiegen. Ich wollte dich nicht korrigieren, sondern nur etwas mehr Informationen in die Diskussion einfließen lassen. Also danke für deine Frage. Ich hätte auf dein Posting konkret Bezug nehmen sollen. Ich habe das zwischenzeitlich nachgeholt.
Gruß
Marcel -
Bei mir Scheiterts jetzt noch an der Zeile hier:
someStream = thisAssembly.GetManifestResourceStream(".......settings.exe");
Ich weis nicht wie genau ich das aufrufen soll um an settings.exe ran zu kommen.
Koopakiller - http://koopakiller.ko.ohost.de/ -
Hallo K.,
Szenario A:
Mal angenommen, Du hast die Datei Settings.exe über [Projekt > Eigenschaften > Ressourcen > Ressource hinzufügen > Vorhandene Datei hinzufügen...] als Ressource hinzugefügt. Nach erfolgtem Import heißt deine Ressource nun Settings.
So extrahierst Du die Datei aus den Ressourcen (einfache Version):string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "settings.exe");
byte[] fileBytes = Properties.Resources.Settings;
File.WriteAllBytes(fileName, fileBytes);
Wenn Du die Neugier hast, zu sehen, was dahintersteckt, kannst Du nach Import der Ressource die Datei Resources.Designer.cs im Editor öffnen und dir die Property Settings ansehen. Du wirst merken, dass hier eine Klasse namens ResourceManager verwendet wird (auf die ich bereits im ersten Posting hingewiesen habe). Über den Aufruf ResourceManager.GetObject("Settings", resourceCulture) wird ein Objekt zurückgegeben, das anschließend in ein byte[]-Array umgewandelt wird.Aber der Zugriff auf die Ressource kann auch low-level und entsprechend performant (wenn z.B. mehrere Resourcen gleichzeitig extrahiert werden sollen) gestaltet werden:
Assembly executingAssembly = this.GetType().Assembly;
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Settings.exe");string exeFileResourceName = "Settings";
string applicationNamespace = "WindowsFormsApplication1";
string propertiesNamespace = String.Format("{0}.Properties", applicationNamespace);
string resourcesNamespace = String.Format("{0}.Resources", propertiesNamespace);
string resgenExtension = "resources";
string completeResourceName = String.Format("{0}.{1}", resourcesNamespace, resgenExtension);
using (Stream resourceStream = executingAssembly.GetManifestResourceStream(completeResourceName)) {
if(resourceStream != null) {
ResourceReader reader = new ResourceReader(resourceStream);
foreach (DictionaryEntry entry in reader) {
if (entry.Key.ToString() == exeFileResourceName) {
byte[] fileBytes = (byte[])entry.Value;
File.WriteAllBytes(fileName, fileBytes);
}
}
}
}
Wie Du siehst, muss der Ressourcenname aus mehreren Informationsteilen zusammengestellt werden (nochmals: s. Chris Sells Artikel oben). Der Ressourcen-Strom wird anschließend an einen ResourceReader weitergegeben, der die DictionaryEntry-Einträge durchsucht, den richtigen findet und das Byte-Array letztendlich auf die Festplatte speichert.
Szenario B (s. Link in Stefans Posting):
Wenn Du hingegen die ausführbare Datei über Projekt > Vorhandenes Element hinzufügen in dein Projekt eingefügt hast (und im Eigenschaftenfenster als Buildvorgang 'Eingebettete Ressource' ausgewählt hast!), kann die Ressource über einen voll qualifizierten Namen angesprochen werden, der sich wie folgt zusammensetzt:
[Standardnamespace].[Relativer Projektpfad].[DateiName]D.h. wenn dein Standardnamespace (Projekt > Eigenschaften > Anwendung) z.B. WindowsFormsApplication1 lautet und Du die Datei im Projektordner EXE gespeichert hast, würde der Ressourcenname so aussehen:
WindowsFormsApplication1.EXE.Settings.exeUnd falls die ausführbare Datei im Projekt-Stammordner residiert:
WindowsFormsApplication1.Settings.exe
Gruß
Marcel- Bearbeitet Marcel RomaModerator Mittwoch, 7. Dezember 2011 11:25 Text verschoben
- Als Antwort markiert KK Senior Mittwoch, 7. Dezember 2011 18:38