c# - 如何从DLL中提取字符串资源

标签 c# dll pinvoke

我正在制作管理系统文件扩展名的应用程序,但遇到了问题。

系统扩展,如 .jpg.exe.dll.png。 txt等有一个注册表值叫做FriendlyTypeName,比如一个jpeg文件的FriendlyTypeName@%SystemRoot%\System32\shell32 .dll,-30596。显示值取决于当前语言。

如何使用 C# 从资源 ID 中提取字符串值(例如:-30596)?我想可以使用 p/invoke 提取字符串(我不确定)。

最佳答案

可以使用LoadStringLoadIcon 等提取资源。但是,hInstance 必须与应用程序的hInstance< 不同,否则,你将只能从你自己的.exe中提取资源。如果要从系统库等外部 DLL 中提取任何资源,必须通过调用 LoadLibrary 获取要提取的 DLL 的 hInstance,然后调用 FreeLibrary 完成文件使用。

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int LoadString(IntPtr hInstance, int ID, StringBuilder lpBuffer, int nBufferMax);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeLibrary(IntPtr hModule);

private string ExtractStringFromDLL(string file, int number) {
    IntPtr lib = LoadLibrary(file);
    StringBuilder result = new StringBuilder(2048);
    LoadString(lib, number, result, result.Capacity);
    FreeLibrary(lib);
    return result.ToString();
}

StringBuilder 最大容量为 2048(如果您愿意,可以更改该值)。

这是一个例子:

string loadedString = ExtractStringFromDLL("shell32.dll", 30596);
Debug.Write(loadedString);

Windows 的默认相对路径是 %SystemRoot%\system32,除非您从非系统 DLL 中提取字符串,否则不需要包含完整路径。

不要忘记从资源编号中删除 - 符号,因为负数表示 FriendlyTypeName 的资源 ID,而 LoadString 需要正数作为资源ID。

编辑:您还可以从 .exe 文件和任何包含资源的文件中提取资源。

关于c# - 如何从DLL中提取字符串资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41968416/

相关文章:

c# - 无法加载文件或程序集或其依赖项之一。该系统找不到指定的文件

c# - 我可以在安装 NuGet 包时解决添加这些 .dll 问题吗?

c# - 如何正确对齐 SHELLSTATE 结构的字段?

c# - 如何根据唯一标识符动态创建安装文件?

c# - C#列表迭代性能

c# - 如何从 DLL 设置委托(delegate)/回调(C 和 C# 之间的互操作)

c++ - 如何在 dll 中创建一个 shared_ptr 并通过工厂函数导出它?

c# - 来自 C# 的 PInvoke AuthzAccessCheck 给出错误 87 : invalid parameter

c# - P/从 C# : Call functions of returned object 调用

c# - MVC 5 'Cannot create an instance of an interface' 中的接口(interface)问题