如何从exe文件中提取与用于创建此exe的文件相同的.ico文件?

时间:2016-07-04 12:46:26

标签: c# .net windows .net-3.5

我试图制作某种SFX:让程序在另一个wrapped.exe周围生成wrap.exe。

Wrapping.exe将wrapped.exe作为资源嵌入,并在执行时将wrapped.exe保存到临时文件夹中,使用特定的命令行参数执行然后删除。 wrapped.exe并不总是.Net程序,我也没有源代码。

wrapped.exe应该在.Net 3.5中完成,可以在Windows 7 SP1和更高版本上使用,而不需要任何先前的.Net安装。

使用.Net 4.6中的Roselyn通过C#程序生成Wrapping.exe。

我需要可以通过资源管理器将wrapped.exe视为wrapped.exe。我使用硬编码的.ico文件进行了成功的测试。代码看起来像这样(简化):

var compilation = CSharpCompilation.Create(...);
var resourceDescription = new ResourceDescription( resourceName: "SFX.resourceName",
                                                   dataProvider: () => File.OpenRead("wrapped.exe"),
                                                   isPublic:     false);

using (var iconStream = File.OpenRead(@"wrapped.ico"))
using (var peStream = File.Create("wrapping.exe"))
using (var pdbStream = File.Create("wrapping.pdb"))
using (var win32resStream = compilation.CreateDefaultWin32Resources(
                                                              versionResource:  true,
                                                              noManifest:       false,
                                                              manifestContents: null,
                                                              iconInIcoFormat:  iconStream))
{
    var emitResult = compilation.Emit( peStream:          peStream,
                                       pdbStream:         pdbStream,
                                       manifestResources: new[] { resourceDescription },
                                       win32Resources:    win32resStream,
                                       options:           new EmitOptions(subsystemVersion: SubsystemVersion.Windows7));
  return emitResult;
}

现在我尝试从" wrapped.exe"获取iconStream。我试图替换:

using (var iconStream = File.OpenRead(@"wrapped.ico"))

使用:

var iconStream = new MemoryStream();
Icon icon = Icon.ExtractAssociatedIcon("wrapped.exe");
icon.Save(iconStream);
iconStream.Seek(0, SeekOrigin.Begin);

但我只得到一个32 * 32的图标。

如何提取完全相同的.ico文件(包括所有格式,例如16 * 16 32位BMP,32 * 32 32位BMP,48 * 48 32位BMP,64 * 64 32位BMP和256 * 256 32位PNG)用于创建' wrapped.exe'?

2 个答案:

答案 0 :(得分:1)

使用IconLib非常容易。回复已经在this question:Thx到@Plutonix

使用以下辅助函数(当然,提取图标文件名不会被硬编码):

static Stream GetIconStream_ExtractIconUsingIconLib(string fileToExecute)
{
    var multiIcon = new MultiIcon();
    multiIcon.Load(fileToExecute);

    var extractedicoFileName = @"c:\temp\icon.ico";
    multiIcon.Save(extractedicoFileName, MultiIconFormat.ICO);

    return File.OpenRead(extractedicoFileName);
}

我们只需要替换:

File.OpenRead(@"wrapped.ico")

GetIconStream_ExtractIconUsingIconLib("wrapped.exe")

这为我们提供了完整的解决方案:

var compilation = CSharpCompilation.Create(...);
var resourceDescription = new ResourceDescription( resourceName: "SFX.resourceName",
                                                   dataProvider: () => File.OpenRead("wrapped.exe"),
                                                   isPublic:     false);

using (var iconStream = GetIconStream_ExtractIconUsingIconLib("wrapped.exe"))
using (var peStream = File.Create("wrapping.exe"))
using (var pdbStream = File.Create("wrapping.pdb"))
using (var win32resStream = compilation.CreateDefaultWin32Resources(
                                                              versionResource:  true,
                                                              noManifest:       false,
                                                              manifestContents: null,
                                                              iconInIcoFormat:  iconStream))
{
    var emitResult = compilation.Emit( peStream:          peStream,
                                       pdbStream:         pdbStream,
                                       manifestResources: new[] { resourceDescription },
                                       win32Resources:    win32resStream,
                                       options:           new EmitOptions(subsystemVersion: SubsystemVersion.Windows7));
  return emitResult;
}

答案 1 :(得分:0)

也有从事这项工作的在线网站 https://extracico.com/