为了账号安全,请及时绑定邮箱和手机立即绑定

如果有其它的简单实现方法也可以写出来,大家帮帮忙

如果有其它的简单实现方法也可以写出来,大家帮帮忙

C#
桃花长相依 2023-01-12 19:15:45

很简单,我要实现修改EXE文件图标的功能,须要用于如下函数。
BeginUpdateResource
UpdateResource
EndUpdateResource

其中UpdateResource我不会用。函数原型如下。
-----------------------------
函数功能:该函数增加,删除,或替代某可执行文件中的资源。

函数原型:BOOL UPdateResource(HANDLE hUpdate,LPCTSTR lPTyPe,LPCTSTR IPName,WORD wLanguage,LPVOID lgData,DWORD cbData);

参数:

hUpdate:指定更新文件句柄。此句柄由BeginUpdateResource函数返回。

lpType:指向说明将被更新的资源类型的字符串,它以NULL为终止符。这个参数可以是一个通过宏MAKENTRESOURCE传递的整数值,含义参见EnumResLangProc\lpType。

lpName:指向说明待被更新的资源名称的字符串,它以NULL为终止符。这个参数可以是一个通过宏MAKEINTRESOURCE传递的整数值。

wLanguage:指定将被更新资源的语言标识。要了解基本的语言标识符以及由这些标识符组成的字语言标识符的列表,可参见宏MAKELANGID。

lpData:指向被插入可执行文件的资源数据的指针。如果资源是预定义类型值之一,那么数据必须是有效且适当排列的。注意这是存储在可执行文件中原始的一进制数据,而不是由Loadlcon,LoadString或其他装载特殊资源函数提供的数据。所有包含字符串、文本的数据必须是Unicode格式;IpData不能指向ANSI数据。

如果lpData为NULL,所指定的资源将从可执行文件中被删除。

cbData:指定lpData中的资源数据数据大小,以字节计数。

返回值:如果函数运行成功,返回值为非零;如果函数运行失败,返回值为零。若想获得更多的错误信息,请调用GetLastError函数。

注意:应用程序重复使用UpdateResource去改变资源数据。每次UpdateResource调用都要占用系统内部的一个增加、删除、替代的列表,而实际上并没有将数据写到可执行文件中。应用程序必须通过使用EndUpdateResource函数将每次积累的变化写入可执行文件中。
------------------------------
这是C的函数原型,在C#中用什么表示呀?
请大家给我写出完整代码(从打开到写入完成),在此先谢过啦!

查看完整描述

2 回答

?
慕雪6442864

TA贡献1552条经验 获得超5个赞

建一个Win32函数的工具类如下:  
public static class Win32Api
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr BeginUpdateResource(string pFileName, [MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
}

然后像C#方法一样调用就行了。
比如:(示意代码,未验证)

string fileName = @"XXX\XXX.xxx";
// 获得资源句柄
IntPtr hResource = Win32Api.BeginUpdateResource(fileName, false);
if (hResource.ToInt32() == 0) {
throw new Win32Exception(Marshal.GetLastWin32Error());
}
string fileToUpdate = @"YYY\YYY.yyy";
// 累积更新
if (Win32Api.UpdateResource(hResource, "FILE", fileToUpdate, 0, null, 0) == false) {
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
// 写入更新
if (Win32Api.EndUpdateResource(hResource, false) == false) {
throw new Win32Exception(Marshal.GetLastWin32Error());
}


查看完整回答
反对 回复 2023-01-15
?
浮云间

TA贡献1579条经验 获得超3个赞

简单,我要实现修改EXE文件图标的功能,须要用于如下函数。 
BeginUpdateResource 
UpdateResource 
EndUpdateResource 

其中UpdateResource我不会用。函数原型如下。 
----------------------------- 
函数功能:该函数增加,删除,或替代某可执行文件中的资源。 

函数原型:BOOL UPdateResource(HANDLE hUpdate,LPCTSTR lPTyPe,LPCTSTR IPName,WORD wLanguage,LPVOID lgData,DWORD cbData); 

参数: 

hUpdate:指定更新文件句柄。此句柄由BeginUpdateResource函数返回。 

lpType:指向说明将被更新的资源类型的字符串,它以NULL为终止符。这个参数可以是一个通过宏MAKENTRESOURCE传递的整数值,含义参见EnumResLangProc\lpType。 

lpName:指向说明待被更新的资源名称的字符串,它以NULL为终止符。这个参数可以是一个通过宏MAKEINTRESOURCE传递的整数值。 

wLanguage:指定将被更新资源的语言标识。要了解基本的语言标识符以及由这些标识符组成的字语言标识符的列表,可参见宏MAKELANGID。 

lpData:指向被插入可执行文件的资源数据的指针。如果资源是预定义类型值之一,那么数据必须是有效且适当排列的。注意这是存储在可执行文件中原始的一进制数据,而不是由Loadlcon,LoadString或其他装载特殊资源函数提供的数据。所有包含字符串、文本的数据必须是Unicode格式;IpData不能指向ANSI数据。 

如果lpData为NULL,所指定的资源将从可执行文件中被删除。 

cbData:指定lpData中的资源数据数据大小,以字节计数。 

返回值:如果函数运行成功,返回值为非零;如果函数运行失败,返回值为零。若想获得更多的错误信息,请调用GetLastError函数。 

注意:应用程序重复使用UpdateResource去改变资源数据。每次UpdateResource调用都要占用系统内部的一个增加、删除、替代的列表,而实际上并没有将数据写到可执行文件中。应用程序必须通过使用EndUpdateResource函数将每次积累的变化写入可执行文件中。 
------------------------------ 
这是C的函数原型,在C#中用什么表示呀? 
请大家给我写出完整代码(从打开到写入完成),在此先谢过啦! 

如果有其它的简单实现方法也可以写出来。
问题补充:看清题目(用C#实现),如果谁能做出来,多少分我都给,反正我不想用百度知道了!

建一个Win32函数的工具类如下: 
public static class Win32Api 

[DllImport("kernel32.dll", SetLastError = true)] 
public static extern IntPtr BeginUpdateResource(string pFileName, [MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources); 

[DllImport("kernel32.dll", SetLastError = true)] 
public static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData); 

[DllImport("kernel32.dll", SetLastError = true)] 
public static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard); 


然后像C#方法一样调用就行了。 
比如:(示意代码,未验证) 

string fileName = @"XXX\XXX.xxx"; 
// 获得资源句柄 
IntPtr hResource = Win32Api.BeginUpdateResource(fileName, false); 
if (hResource.ToInt32() == 0) { 
throw new Win32Exception(Marshal.GetLastWin32Error()); 

string fileToUpdate = @"YYY\YYY.yyy"; 
// 累积更新 
if (Win32Api.UpdateResource(hResource, "FILE", fileToUpdate, 0, null, 0) == false) { 
throw new Win32Exception(Marshal.GetLastWin32Error()); 


// 写入更新 
if (Win32Api.EndUpdateResource(hResource, false) == false) { 
throw new Win32Exception(Marshal.GetLastWin32Error());

 


查看完整回答
反对 回复 2023-01-15
  • 2 回答
  • 0 关注
  • 7 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信