如何在C#中查找资源(pinvoke)字符串资源?

时间:2011-11-23 12:58:44

标签: .net resources c#-2.0 pinvoke

我搜索了很多,但我找不到如何加载ID为字符串的资源。教程Here很好,但不会那样做。有人知道怎么做吗?这是我的结构。我想加载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 个答案:

答案 0 :(得分:2)

  

@ “C:\ Users \用户为myuser \桌面\ 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文件夹,shell实际上并没有显示c:\ users \ yourname \ desktop文件夹的内容,你得到了几个文件夹的混合。当您在代码中引用该文件夹时,不会发生这种混合。该文件的一个可能位置是c:\ users \ public \ desktop。以正确的方式解决此问题,确保DLL与主EXE位于同一目录中。项目+添加现有项目,导航到DLL,以便将其添加到项目中。选择它并将Copy to Output Directory属性设置为“Copy if newer”。

编辑后:资源类型参数也可能有问题。使用“#23”或将参数类型声明为整数,这样就可以传递23。