【发布时间】:2010-11-08 20:31:30
【问题描述】:
我正在尝试以编程方式更改外部可执行文件的图标。我用谷歌搜索并找到了很多关于使用 C++ 的这个问题的信息。基本上,我需要使用 BeginUpdateResource、UpdateResource 和 EndUpdateResource。问题是 - 我不知道在 C# 中将什么传递给 UpdateResource。
这是我目前的代码:
class IconChanger
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr BeginUpdateResource(string pFileName,
[MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage,
IntPtr lpData, uint cbData);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
public enum ICResult
{
Success,
FailBegin,
FailUpdate,
FailEnd
}
public ICResult ChangeIcon(string exeFilePath, byte[] iconData)
{
// Load executable
IntPtr handleExe = BeginUpdateResource(exeFilePath, false);
if (handleExe == null)
return ICResult.FailBegin;
// Get language identifier
CultureInfo currentCulture = CultureInfo.CurrentCulture;
int pid = ((ushort)currentCulture.LCID) & 0x3ff;
int sid = ((ushort)currentCulture.LCID) >> 10;
ushort languageID = (ushort)((((ushort)pid) << 10) | ((ushort)sid));
// Get pointer to data
GCHandle iconHandle = GCHandle.Alloc(iconData, GCHandleType.Pinned);
// Replace the icon
if (UpdateResource(handleExe, "#3", "#1", languageID, iconHandle.AddrOfPinnedObject(), (uint)iconData.Length))
{
if (EndUpdateResource(handleExe, false))
return ICResult.Success;
else
return ICResult.FailEnd;
}
else
return ICResult.FailUpdate;
}
}
关于 lpType - 在 C++ 中,您传递 RT_ICON(或 RT_GROUP_ICON)。我应该在 C# 中传递什么值? lpName 参数也有同样的问题。 我不确定语言标识符(我在 Internet 上找到的),因为我无法对其进行测试。 我也不确定我是否提供了适当的图标数据。目前,iconData 包含来自 .ico 文件的字节。
谁能指出我正确的方向?
非常感谢。
【问题讨论】: