UpdateResource不能使用lpType作为字符串

本文关键字:字符串 lpType 不能 UpdateResource | 更新日期: 2023-09-27 18:04:36

p/调用声明:

[DllImport("kernel32.dll")]
static extern bool UpdateResource(IntPtr hUpdate, IntPtr lpType, IntPtr lpName, ushort wLanguage, byte[] lpData, uint cbData);
[DllImport("kernel32.dll")]
static extern bool UpdateResource(IntPtr hUpdate, string lpType, int lpName, ushort wLanguage, byte[] lpData, uint cbData);
[DllImport("kernel32.dll")]
static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources);
[DllImport("kernel32.dll")]
static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
我代码:

var hUpdate = BeginUpdateResource(FilePath, false);
var BMP = File.ReadAllBytes(BmpPath);
UpdateResource(hUpdate, "2", 123, 1033, BMP, (uint)BMP.Length);
UpdateResource(hUpdate, "#2", 123, 1033, BMP, (uint)BMP.Length);
UpdateResource(hUpdate, "RT_BITMAP", 123, 1033, BMP, (uint)BMP.Length);
UpdateResource(hUpdate, "BITMAP", 123, 1033, BMP, (uint)BMP.Length);
EndUpdateResource(hUpdate, false);

以上UpdateResource呼叫均无效。它们在名为#2, RT_BITMAP, BITMAP的新资源类型下添加新资源,而不是更新现有资源。

UpdateResource的p/Invoke声明中,如果我将string lpType重载到IntPtr lpType并传递给它new IntPtr(2),一切都可以工作,但我不想使用这种解决方案,因为有时我还需要自定义资源类型的string lpType和重载将需要在我当前的代码设计中进行太多更改。

MSDN:

lpType[在]

类型:LPCTSTR

要更新的资源类型。或者,与其使用指针,该参数可以是MAKEINTRESOURCE(ID),其中ID为整数值,表示预定义的资源类型。如果第一个字符字符串的开头是一个井号(#),然后是剩下的字符表示指定整数标识符的十进制数资源类型。例如,字符串"#258"表示标识符258。

知道为什么我不能通过传递lpType字符串来更新现有的位图吗?我正在做的正是MSDN中规定的。

PS:我绝对需要传递lpType一个字符串,不能使用IntPtr重载,因为上述原因(当前代码设计需要太多的更改)。

UpdateResource不能使用lpType作为字符串

MSDN很可能是错误的。

lpName参数的文档说"当创建一个新资源时,不要使用以'#'字符开头的字符串作为该参数"。我想同样的限制也适用于lpType

您可以在不改变其余代码结构的情况下修复此问题。

定义UpdateResource的两个重载,但使它们私有并重命名(可能为UpdateResourceW)。

然后在c#中定义自己的公共UpdateResource函数。这应该检查lpType参数。如果类型以#开头,将其转换为整型并调用IntPtr lpType重载,否则使用string lpType重载。 因此,您可以在整个代码中使用字符串作为资源类型,并在一个地方处理此细节。