2017-01-31 15 views
1

Я делаю приложение для управления расширениями системных файлов, у меня есть проблема.Как извлечь строковый ресурс из DLL

системы расширения, как .jpg, .exe, .dll, .png, .txt и т.д. имеет значение реестра называется FriendlyTypeName, например, FriendlyTypeName файла в формате JPEG является @%SystemRoot%\System32\shell32.dll,-30596. Отображаемое значение зависит от текущего языка.

Как извлечь строковое значение из идентификатора ресурса (например: -30596) с использованием C# ?. Я думаю, строки могут быть извлечены с помощью p/invoke (я не уверен).

+0

Не используйте C#; вместо этого используйте C++/CLI с вызовами API Win32. –

+0

Win32 устарел и даже не имеет визуального дизайнера в первую очередь. C# поддерживает вызовы Win32 с использованием p/invoke. Я хочу извлечь строки из системных DLL, поэтому я спрашиваю. –

ответ

2

Ресурсы могут быть экстракт использованием LoadString, LoadIcon и т.д. Тем не менее, hInstance должен отличаться от вашего приложения hInstance, в противном случае, вы будете только в состоянии извлекать ресурсы из собственного .exe. Если вы хотите извлечь какие-либо ресурсы из внешних библиотек DLL, таких как системные библиотеки, вы должны получить hInstance из DLL, которую хотите извлечь, вызывая LoadLibrary и звоните 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 и LoadString требует положительных чисел в качестве идентификатора ресурса.

EDIT: Вы также можете извлечь ресурсы из .exe файлов и любых файлов, содержащих ресурсы.

+0

Большое спасибо. Я так долго искал решение. Изменение: «private string ExtractStringFromDLL» на «public static string ExtractStringFromDLL» позволило использовать в powershell –

 Смежные вопросы

  • Нет связанных вопросов^_^