我的资源部分中的可执行文件中嵌入的图像很少。 我按照以下步骤创建了可执行文件:
resgen myResource.resx
csc file.cs /res:myResource.resources
4我正在访问这些图片:
ResourceManager resources = new ResourceManager("myResource", Assembly.GetExecutingAssembly());
Image foo = (System.Drawing.Image)(resources.GetObject("image1"));
这一切都按预期工作正常。现在我想将嵌入的图像更改为一些新图像。这就是我目前正在做的事情:
class foo
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, string wLanguage, Byte[] lpData, uint cbData);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
public static void Main(string[] args)
{
IntPtr handle = BeginUpdateResource(args[0], false);
if (handle.ToInt32() == 0)
throw new Exception("File Not Found: " + fileName + " last err: " + Marshal.GetLastWin32Error());
byte[] imgData = File.ReadAllBytes("SetupImage1.jpg");
int fileSize = imgData.Length;
Console.WriteLine("Updaing resources");
if (UpdateResource(handle, "Image", "image1", "image1", imgData, (uint)fileSize))
{
EndUpdateResource(handle, false);
Console.WriteLine("Update successfully");
}
else
{
Console.WriteLine("Failed to update resource. err: {0}", Marshal.GetLastWin32Error());
}
}
}
上面的代码是为指定的图像添加新资源(IMAGE
标题内部带有一些随机数,如Resource hacker
中所示),但我想修改{{{}的现有资源数据1}}。
我确信我使用一些无效的参数调用image1
。
任何人都能指出这一点吗?
我正在使用.NET版本2
谢谢,
维克拉姆
答案 0 :(得分:8)
我认为您在.NET资源和Win32资源之间存在混淆。您使用/res
参数嵌入csc.exe
嵌入的资源是您可以使用ResourceManager
代码段代码成功读取的.NET资源。
Win32资源是另一种野兽,与托管的.NET世界一般并不太“兼容”,尽管你确实可以使用/win32Res
参数将它们添加到.NET exe中 - 请注意细微差别: - )
现在,如果您想修改嵌入式.NET资源,我认为在框架本身中没有类可以执行它,但您可以使用Mono.Cecil库。这里有一个示例:C# – How to edit resource of an assembly?
如果你想修改嵌入式Win32资源,你的代码需要一些修复,这里有一个稍微修改过的版本,最重要的区别在于UpdateResource
的声明:
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, short wLanguage, byte[] lpData, int cbData);
[DllImport("kernel32.dll")]
static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
public static void Main(string[] args)
{
IntPtr handle = BeginUpdateResource(args[0], false);
if (handle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error()); // this will automatically throw an error with the appropriate human readable message
try
{
byte[] imgData = File.ReadAllBytes("SetupImage1.jpg");
if (!UpdateResource(handle, "Image", "image1", (short)CultureInfo.CurrentUICulture.LCID, imgData, imgData.Length))
throw new Win32Exception(Marshal.GetLastWin32Error());
}
finally
{
EndUpdateResource(handle, false);
}
}
答案 1 :(得分:1)
这是不可能的。您无法修改正在运行的编译文件。
答案 2 :(得分:0)
我相信您可以在运行时添加新图像,但无法更新基本上只在内存中保存的资源。
如果你在运行时添加一个资源,它就存在,但我不认为它是编译的,因此我不认为你可以访问它。
您是否有理由不使用内容?