wake-up-neo.com

Wie kann ich eine Datei aus einer eingebetteten Ressource extrahieren und auf der Festplatte speichern?

Ich versuche, den folgenden Code mit CSharpCodeProvider zu kompilieren. Die Datei wurde erfolgreich kompiliert, aber wenn ich auf die generierte EXE-Datei klicke, erhalte ich eine Fehlermeldung (Windows sucht nach einer Lösung für dieses Problem) und es passiert nichts.

Wenn ich den folgenden Code mit CSharpCodeProvider kompiliere, habe ich das MySql.Data.dll als eingebettete Ressourcendatei mit folgender Codezeile:

if (provider.Supports(GeneratorSupport.Resources))
    cp.EmbeddedResources.Add("MySql.Data.dll");

Die Datei wurde erfolgreich eingebettet (da die Dateigröße zugenommen hat).

Im folgenden Code versuche ich, die eingebettete DLL) - Datei zu extrahieren und auf System32 zu speichern, aber der folgende Code funktioniert aus irgendeinem Grund nicht.

namespace ConsoleApplication1
{
    class Program
    {
        public static void ExtractSaveResource(String filename, String location)
        {
            //Assembly assembly = Assembly.GetExecutingAssembly();
            Assembly a = .Assembly.GetExecutingAssembly();
            //Stream stream = Assembly.GetManifestResourceStream("Installer.Properties.mydll.dll"); // or whatever
            //string my_namespace = a.GetName().Name.ToString();
            Stream resFilestream = a.GetManifestResourceStream(filename);
            if (resFilestream != null)
            {
                BinaryReader br = new BinaryReader(resFilestream);
                FileStream fs = new FileStream(location, FileMode.Create); // Say
                BinaryWriter bw = new BinaryWriter(fs);
                byte[] ba = new byte[resFilestream.Length];
                resFilestream.Read(ba, 0, ba.Length);
                bw.Write(ba);
                br.Close();
                bw.Close();
                resFilestream.Close();
            }
            // this.Close();
        }

        static void Main(string[] args)
        {
            try
            {
                string systemDir = Environment.SystemDirectory;
                ExtractSaveResource("MySql.Data.dll", systemDir);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadKey();
            }
        }
    }
}

Wie kann ich die als Ressource eingebettete DLL Datei extrahieren und auf System32 speichern?

47
Rafik Bari

Ich habe festgestellt, dass der einfachste Weg dies zu tun ist, Properties.Resources Und File zu verwenden. Hier ist der Code, den ich benutze ...

Für Binärdateien: File.WriteAllBytes(fileName, Properties.Resources.file);

Für Textdateien: File.WriteAllText(fileName, Properties.Resources.file);

57
Thomas Sapp

Ich würde vorschlagen, es einfacher zu machen. Ich gehe davon aus, dass die Ressource vorhanden und die Datei beschreibbar ist (dies kann ein Problem sein, wenn es sich um Systemverzeichnisse handelt).

public void WriteResourceToFile(string resourceName, string fileName)
{
    using(var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
    {
        using(var file = new FileStream(fileName, FileMode.Create, FileAccess.Write))
        {
            resource.CopyTo(file);
        } 
    }
}
69

Ich habe diese (getestete) Methode verwendet:

OutputDir: Speicherort, an den Sie die Ressource kopieren möchten

ResourceLocation: Namespace (+ dirnames)

Dateien: Liste der Dateien im Ressourcenverzeichnis, die Sie kopieren möchten.

    private static void ExtractEmbeddedResource(string outputDir, string resourceLocation, List<string> files)
    {
        foreach (string file in files)
        {
            using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceLocation + @"." + file))
            {
                using (System.IO.FileStream fileStream = new System.IO.FileStream(System.IO.Path.Combine(outputDir, file), System.IO.FileMode.Create))
                {
                    for (int i = 0; i < stream.Length; i++)
                    {
                        fileStream.WriteByte((byte)stream.ReadByte());
                    }
                    fileStream.Close();
                }
            }
        }
    }
30
M ten Klooster

Oder mit einer Erweiterungsmethode ...

 /// <summary>
 /// Retrieves the specified [embedded] resource file and saves it to disk.  
 /// If only filename is provided then the file is saved to the default 
 /// directory, otherwise the full filepath will be used.
 /// <para>
 /// Note: if the embedded resource resides in a different Assembly use that
 /// Assembly instance with this extension method.
 /// </para>
 /// </summary>
 /// <example>
 /// <code>
 ///       Assembly.GetExecutingAssembly().ExtractResource("Ng-setup.cmd");
 ///       OR
 ///       Assembly.GetExecutingAssembly().ExtractResource("Ng-setup.cmd", "C:\temp\MySetup.cmd");
 /// </code>
 /// </example>
 /// <param name="Assembly">The Assembly.</param>
 /// <param name="resourceName">Name of the resource.</param>
 /// <param name="fileName">Name of the file.</param>
 public static void ExtractResource(this Assembly assembly, string filename, string path=null)
 {
     //Construct the full path name for the output file
     var outputFile = path ?? [email protected]"{Directory.GetCurrentDirectory()}\{filename}";

     // If the project name contains dashes replace with underscores since 
     // namespaces do not permit dashes (underscores will be default to).
     var resourceName = $"{Assembly.GetName().Name.Replace("-","_")}.{filename}";

     // Pull the fully qualified resource name from the provided Assembly
     using (var resource = Assembly.GetManifestResourceStream(resourceName))
     {
         if (resource == null)
             throw new FileNotFoundException($"Could not find [{resourceName}] in {Assembly.FullName}!");

         using (var file = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
         {
             resource.CopyTo(file);
         }
     }
 }
2
BillKrat

Das funktioniert einwandfrei!

public static void Extract(string nameSpace, string outDirectory, string internalFilePath, string resourceName)
{
    //nameSpace = the namespace of your project, located right above your class' name;
    //outDirectory = where the file will be extracted to;
    //internalFilePath = the name of the folder inside visual studio which the files are in;
    //resourceName = the name of the file;
    Assembly assembly = Assembly.GetCallingAssembly();

    using (Stream s = Assembly.GetManifestResourceStream(nameSpace + "." + (internalFilePath == "" ? "" : internalFilePath + ".") + resourceName))
    using (BinaryReader r = new BinaryReader(s))
    using (FileStream fs = new FileStream(outDirectory + "\\" + resourcename, FileMode.OpenOrCreate))
    using (BinaryWriter w = new BinaryWriter(fs))
    {
        w.Write(r.ReadBytes((int)s.Length));
    }
}

Anwendungsbeispiel:

public static void ExtractFile()
{
    String local = Environment.CurrentDirectory; //gets current path to extract the files

    Extract("Geral", local, "Arquivos", "bloquear_vbs.vbs");
}    

Wenn dies immer noch nicht hilft, probieren Sie dieses Video aus: https://www.youtube.com/watch?v=_61pLVH2qPk

2
Diego Fortes

Versuchen Sie, Ihre Ziel-Assembly in ein MemoryStream einzulesen und dann in ein FileStream zu speichern (denken Sie daran, dass dieser Code nicht getestet wurde):

Assembly assembly = Assembly.GetExecutingAssembly();

using (var target = Assembly.GetManifestResourceStream("MySql.Data.dll"))
{
    var size = target.CanSeek ? Convert.ToInt32(target.Length) : 0;

    // read your target Assembly into the MemoryStream
    MemoryStream output = null;
    using (output = new MemoryStream(size))
    {
        int len;
        byte[] buffer = new byte[2048];

        do
        {
            len = target.Read(buffer, 0, buffer.Length);
            output.Write(buffer, 0, len);
        } 
        while (len != 0);
    }

    // now save your MemoryStream to a flat file
    using (var fs = File.OpenWrite(@"c:\Windows\System32\MySql.Data.dll"))
    {
        output.WriteTo(fs);
        fs.Flush();
        fs.Close()
    }
}
0