我想将许多资源添加到exe。我注意到我只能通过一些资源这样做:
// BeginUpdate();
// for (int i = 0; i < count; i++)
// UpdateResource();
// EndUpdate();
因为WinApi中似乎有一个bug或者什么。我现在正试着这样做:
// for (int i = 0; i < count; i++)
// {
// BeginUpdate();
// UpdateResource();
// EndUpdate();
// }
但当然它不会发生。 GetLastError()
会返回有时错误代码5(访问被拒绝)和110(系统无法打开指定的设备或文件。) 。它适用于某些资源,然后错误110成组。有时错误5会出现。我该如何解决这些错误?我必须添加1000多个资源,并且该函数必须完全成功或失败,之间没有任何内容。
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr BeginUpdateResource([MarshalAs(UnmanagedType.LPStr)] string filename, bool deleteExistingResources);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern bool UpdateResource(IntPtr resource, [MarshalAs(UnmanagedType.LPStr)] string type, [MarshalAs(UnmanagedType.LPStr)] string name, ushort language, IntPtr data, uint dataSize);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool EndUpdateResource(IntPtr resource, bool discardChanges);
private static void addResources(string filename, int count)
{
// 1. delete existing resources
IntPtr handle = BeginUpdateResource(filename, true);
Console.WriteLine(EndUpdateResource(handle, false));
// 2. add resources
for (int i = 0; i < count; i++)
{
handle = BeginUpdateResource(filename, false);
string text = Utils.randomString(16);
if (!UpdateResource(handle, "TEST", "" + i, 0, Marshal.StringToHGlobalAnsi(text), (uint) text.Length))
Console.WriteLine("update error: " + GetLastError() + ", " + i);
if (!EndUpdateResource(handle, false))
Console.WriteLine("endupdate error: " + GetLastError() + ", " + i);
}
}
答案 0 :(得分:1)
似乎只有一种方法可以解决此错误:重试
EndUpdateResource(...)
无缘无故地失败(程序员的观点)。原因可能是AnitVir或Windows检查文件。它可能会连续几次或多次失败。特别是当你多次修改资源时会发生这种情况。
解决方案:重试从BeginUpdateResource(...)
到EndUpdateResource(...)
的所有内容
if (EndUpdateResource(...))
// success
else
// retry
答案 1 :(得分:0)
你的代码错了。您正在循环中调用BeginUpdateResource()
和EndUpdateResource()
。它应该只是:
handle = BeginUpdateResource(...);
for(...) {
UpdateResource(...);
}
EndUpdateResource(...);
随着UpdateResource()
累积的更改将被一起写入(这是EndUpdateResource()
的工作),因此它为您提供“全有或全无”的语义。
有关详情,请参阅UpdateResource()
文档的备注部分:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648049%28v=vs.85%29.aspx