Vik*_*exe 8 c# resources .net-2.0
我在资源部分的可执行文件中嵌入了很少的图像.我按照以下步骤创建了我的可执行文件:
resgen myResource.resxcsc file.cs /res:myResource.resources4我正在访问这些图像:
ResourceManager resources = new ResourceManager("myResource", Assembly.GetExecutingAssembly());
Image foo = (System.Drawing.Image)(resources.GetObject("image1"));
Run Code Online (Sandbox Code Playgroud)
这一切都按预期工作正常.现在我想将嵌入的图像更改为一些新图像.这就是我目前正在做的事情:
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是为指定的图像添加一个新资源(内部IMAGE标题带有一些随机数,如图所示Resource hacker),但我想修改现有的资源数据image1.
我确信我正在调用UpdateResource一些无效的论点.
任何人都能指出这一点吗?
我使用的是.NET版本2
谢谢,
维克拉姆
我认为你在.NET资源和Win32资源之间混淆了.您使用/res参数嵌入的csc.exe资源是使用您的ResourceManager代码段成功读取的.NET资源.
Win32资源是另一种野兽,与托管的.NET世界一般并不太"兼容",尽管你确实可以使用/win32Res参数将它们添加到.NET exe中- 请注意细微差别:-)
现在,如果您想修改嵌入式.NET资源,我认为在框架本身中没有类可以执行它,但您可以使用Mono.Cecil库.这里有一个例子可以证明这一点:C# - 如何编辑程序集的资源?
如果你想修改嵌入式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);
}
}
Run Code Online (Sandbox Code Playgroud)