¿Cómo puedo extraer un archivo de un recurso incrustado y guardarlo en el disco?

Estoy intentando comstackr el siguiente código usando CSharpCodeProvider. El archivo se compiló con éxito, pero cuando hago clic en el archivo EXE generado, aparece un error (Windows está buscando una solución a este problema) y no ocurre nada.

Cuando compilo el código a continuación usando CSharpCodeProvider, he agregado MySql.Data.dll como un archivo de recursos incrustado usando esta línea de código:

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

El archivo está incrustado correctamente (porque noté que el tamaño del archivo aumentó).

En el siguiente código, bash extraer el archivo DLL incrustado y guardarlo en System32, pero el código siguiente no funciona por algún motivo.

 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(); } } } } 

¿Cómo puedo extraer el archivo DLL que está incrustado como un recurso y guardarlo en System32?

Sugeriría hacerlo más fácil. Supongo que el recurso existe y el archivo es de escritura (esto podría ser un problema si hablamos de directorios del sistema).

 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); } } } 

Descubrí que la forma más fácil de hacerlo es usar Properties.Resources . Properties.Resources y File . Aquí está el código que uso …

Para archivos binarios: File.WriteAllBytes(fileName, Properties.Resources.file);

Para archivos de texto: File.WriteAllText(fileName, Properties.Resources.file);

He estado usando este método (probado):

OutputDir: ubicación donde desea copiar el recurso

ResourceLocation: Namespace (+ dirnames)

Archivos: lista de archivos dentro de la ubicación de recursos, que desea copiar.

  private static void ExtractEmbeddedResource(string outputDir, string resourceLocation, List 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(); } } } } 

Esto funciona perfectamente!

 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)); } } 

Ejemplo de uso:

 public static void ExtractFile() { String local = Environment.CurrentDirectory; //gets current path to extract the files Extract("Geral", local, "Arquivos", "bloquear_vbs.vbs"); } 

Si esto aún no funciona, prueba este video: https://www.youtube.com/watch?v=_61pLVH2qPk

O usando un método de extensión …

  ///  /// 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. ///  /// Note: if the embedded resource resides in a different assembly use that /// assembly instance with this extension method. ///  ///  ///  ///  /// Assembly.GetExecutingAssembly().ExtractResource("Ng-setup.cmd"); /// OR /// Assembly.GetExecutingAssembly().ExtractResource("Ng-setup.cmd", "C:\temp\MySetup.cmd"); ///  ///  /// The assembly. /// Name of the resource. /// Name of the file. public static void ExtractResource(this Assembly assembly, string filename, string path=null) { //Construct the full path name for the output file var outputFile = path ?? $@"{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); } } } 

Intente leer su ensamblaje de destino en un MemoryStream y luego guarde en un FileStream esta manera (tenga en cuenta que este código no está probado):

 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() } }