问题描述
我想以编程方式更改外部可执行文件的图标。我一派,发现有关使用C ++这个问题的信息。基本上,我需要使用BeginUpdateResource,UpdateResource和EndUpdateResource。现在的问题是 - 我不知道该怎么传递给UpdateResource在C#
I'm trying to change the icon of external executable programmatically. I've googled and found much information about this problem using C++. Basically, I need to use BeginUpdateResource, UpdateResource and EndUpdateResource. The problem is - I don't know what to pass to UpdateResource in C#.
这里的code我到目前为止有:
Here's the code I have so far:
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参数。我不知道有关语言标识符(我发现这是因特网),因为我不能测试它。我也不能确定我是否提供相应的图标数据。目前,iconData包含.ico文件的字节数。
Regarding lpType - in C++, you pass RT_ICON (or RT_GROUP_ICON). What value should I pass in C#?The same question goes for lpName parameter.I'm not sure about language identifier (I found this on Internet) since I cannot test it.I'm also not sure whether I'm providing appropriate icon data. Currently, iconData contains the bytes from .ico file.
任何人都可以点我朝着正确的方向?
Can anybody point me to right direction?
非常感谢你。
推荐答案
只是一些三分球,这是相当难以得到正确的。通过谎报lpType参数传递一个RT_ICON。从字符串更改它的IntPtr并通过(IntPtr的)3。
Just some pointers, this is quite hard to get right. Pass an RT_ICON by lying about the lpType argument. Change it from string to IntPtr and pass (IntPtr)3.
本的lpData参数是相当棘手。你需要传递的数据是由编译资源编译器(RC.EXE)的方式。我不知道,如果它轧液.ico文件的原始数据。唯一合理的事情是尝试读取使用FileStream .ico文件数据到一个byte [],你似乎已经在做这个。我认为功能是真的,旨在从一个二进制映像复制资源到另一个。你的方法工作的胜算并不为零。
The lpData argument is quite tricky. You need to pass the data the way it is compiled by the resource compiler (rc.exe). I have no idea if it mangles the raw data of the .ico file. The only reasonable thing to try is to read the data from the .ico file with FileStream into a byte[], you already seem to be doing this. I think the function was really designed to copy a resource from one binary image to another. Odds of your approach working are not zero.
您也忽略了另外一个潜在的问题,该程序的图标资源ID不一定1.常不,100往往是一个受欢迎的选择,但任何事情都会发生。 EnumResourceNames将需要以使其可靠。该规则是编号最小的ID设置为文件的图标。我实际上并不知道这实际上意味着资源编译器会将最低数量第一,一些API的可能不这样做。
You are also ignoring another potential problem, the resource ID of the icon of the program isn't necessarily 1. It often is not, 100 tends to be a popular choice, but anything goes. EnumResourceNames would be required to make it reliable. The rule is that the lowest numbered ID sets the icon for the file. I'm not actually sure if that really means that the resource compiler puts the lowest number first, something that the API probably doesn't do.
一个很小的故障模式是UpdateResource只能更新编号的资源项,未命名的。使用名字而不是数字的情况并不少见,但图像绝大多数使用号码的图标。
A very small failure mode is that UpdateResource can only updated numbered resource items, not named ones. Using names instead of numbers is not uncommon but the vast majority of images use numbers for icons.
当然,赔率,这将工作没有UAC明显是零。你是黑客,你通常没有写访问文件。
And of course, the odds that this will work without a UAC manifest are zero. You are hacking files that you don't normally have write access to.
这篇关于在C#中使用UpdateResource?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!