如何从 exe 文件中提取与用于创建此 exe 的文件相同的 .ico 文件?
How to extract from exe file the same .ico file as the one used to create this exe?
我正在尝试制作某种 SFX:制作一个程序,在另一个 wrapped.exe 周围生成一个 wrapping.exe。
Wrapping.exe 嵌入 wrapped.exe 作为资源,执行时,wrapped.exe 被保存到临时文件夹中,使用特定的命令行参数执行,然后删除。 wrapped.exe 并不总是 .Net 程序,我没有它的源代码。
wrapping.exe 应该在 .Net 3.5 中完成才能在 Windows 7 SP1 和更高版本上使用,而无需事先安装任何 .Net。
Wrapping.exe 是在 .Net 4.6 中使用 Roselyn 的 C# 程序生成的。
我需要 wrapping.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'?
这很容易使用 IconLib. The response was already in : Thx to @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;
}
也有网站做这项工作
https://extracico.com/
我正在尝试制作某种 SFX:制作一个程序,在另一个 wrapped.exe 周围生成一个 wrapping.exe。
Wrapping.exe 嵌入 wrapped.exe 作为资源,执行时,wrapped.exe 被保存到临时文件夹中,使用特定的命令行参数执行,然后删除。 wrapped.exe 并不总是 .Net 程序,我没有它的源代码。
wrapping.exe 应该在 .Net 3.5 中完成才能在 Windows 7 SP1 和更高版本上使用,而无需事先安装任何 .Net。
Wrapping.exe 是在 .Net 4.6 中使用 Roselyn 的 C# 程序生成的。
我需要 wrapping.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'?
这很容易使用 IconLib. The response was already in
有如下辅助函数(当然提取图标文件名不会硬编码):
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;
}
也有网站做这项工作 https://extracico.com/