Как FindResource (pinvoke) строковый ресурс в C #? - PullRequest
2 голосов
/ 23 ноября 2011

Я много искал, но не мог найти, как загрузить ресурс, идентификатор которого является строкой.Учебник Здесь хорош, но не делает этого.Кто-нибудь знает, как это сделать?Вот моя структура.Я хочу загрузить PNG.


enter image description here


И код:

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr FindResource(IntPtr hModule, string lpName, string lpType);
[DllImport("kernel32.dll")]
static extern IntPtr FindResource(IntPtr hModule, int lpID, string lpType);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);

const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;

void LoadSkin() {
    IntPtr hMod = LoadLibraryEx(@"C:\Users\myuser\Desktop\skin.dll", IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);            
    IntPtr hRes = FindResource(hMod, "BACK.PNG", "23");

    MessageBox.Show(hRes.ToString()); // <- 0 here.

    uint size = SizeofResource(hMod, hRes);
    IntPtr pt = LoadResource(hMod, hRes);

    Bitmap bmp;
    byte[] bPtr = new byte[size];
    Marshal.Copy(pt, bPtr, 0, (int) size);
    using (MemoryStream m = new MemoryStream(bPtr))
        bmp = (Bitmap) Bitmap.FromStream(m);
}

РЕДАКТИРОВАТЬ:

ИсправленоЭто.Проблема была в объявлении FindResource.Для моего случая правильным было:

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr FindResource(IntPtr hModule, string lpName, uint lpType);

1 Ответ

2 голосов
/ 23 ноября 2011

@ "C: \ Users \ myuser \ Desktop \ skin.dll"

Очевидно, что DLL не может быть загружена.Получите лучшую диагностику, написав ее так:

   IntPtr hMod = LoadLibraryEx(@"C:\Users\myuser\Desktop\skin.dll", IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
   if (hMod == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();

Конструктор по умолчанию для класса Win32Exception уже позаботился о том, чтобы выкопать код ошибки Marshal.GetLastWin32Error () и создать для него соответствующее сообщение.*

Вероятно, файл не найден.Вы должны следить за папкой Desktop, оболочка фактически не показывает содержимое папки c: \ users \ yourname \ desktop, вы получаете смесь из нескольких папок.Это смешение не происходит, когда вы ссылаетесь на папку в вашем коде.Одним из возможных мест для файла является c: \ users \ public \ desktop.Решите эту проблему правильным образом, убедитесь, что DLL находится в том же каталоге, что и ваш основной EXE.Проект + Добавить существующий элемент, перейдите к DLL, чтобы он был добавлен в ваш проект.Выберите его и установите для свойства «Копировать в выходной каталог» значение «Копировать, если новее».

После редактирования: аргумент типа ресурса также может вызывать проблемы.Либо используйте "# 23", либо объявите тип аргумента как целое число, чтобы вы могли передать 23.

...