UpdateResource不能将lpType用作字符串

use*_*697 5 .net c# vb.net winapi

P/Invoke声明:

[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);
Run Code Online (Sandbox Code Playgroud)

我的代码:

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);
Run Code Online (Sandbox Code Playgroud)

以上UpdateResource呼叫都不起作用.它们在名为的新资源类型下添加新资源,#2, RT_BITMAP, BITMAP而不是更新现有资源.

在P/Invoke的声明UpdateResource,如果我过载string lpTypeIntPtr lpType,并通过它new IntPtr(2),一切正常,但我不希望使用此解决方案,因为有时我也需要string lpType自定义资源类型和重载需要在我当前的代码设计太多的变化.

MSDN:

lpType [in]

类型:LPCTSTR

要更新的资源类型.或者,该参数可以是MAKEINTRESOURCE(ID),而不是指针,其中ID是表示预定义资源类型的整数值.如果字符串的第一个字符是井号(#),则其余字符表示一个十进制数,指定资源类型的整数标识符.例如,字符串"#258"表示标识符258.

知道为什么我不能通过传递lpType字符串更新现有的位图?我正在做MSDN中所说的.

PS:我绝对需要传递lpType一个字符串,IntPtr因为上面提到的原因而无法通过重载使用(当前代码设计需要进行太多更改).

arx*_*arx 3

MSDN 很可能是错误的。

lpName参数的文档说“创建新资源时,请勿使用以“#”字符开头的字符串作为该参数”。我想同样的限制适用于lpType.

您可以修复此问题,而无需更改其余代码的结构。

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

UpdateResource然后在 C# 中定义您自己的公共函数。这应该检查lpType参数。如果类型以#a 开头,则将其转换为整数并调用IntPtr lpType重载,否则使用string lpType重载。

因此,您可以在整个代码中使用字符串作为资源类型,并在一个位置处理此细节。