C# FindResource没有';虽然资源确实存在,但却找不到

C# FindResource没有';虽然资源确实存在,但却找不到,c#,winapi,resources,pinvoke,C#,Winapi,Resources,Pinvoke,我的。我正在尝试使用WinApi(FindResource)从我的exe加载资源。我已经使用WinApi成功创建了一个字符串资源,并通过PE explorer、资源黑客和十六进制编辑器验证了它们的存在 我不能做的是通过FindResource找到它们。函数完成后,返回一些指针并将LastError设置为0。但是指针b指向无效内存。我尝试了4种不同的方式导入FindResource,结果都是一样的(b1、b2、b3、b4表示每个声明都是b)。我发现我需要先加载Library,让FindResour

我的。我正在尝试使用WinApi(FindResource)从我的exe加载资源。我已经使用WinApi成功创建了一个字符串资源,并通过PE explorer、资源黑客和十六进制编辑器验证了它们的存在

我不能做的是通过FindResource找到它们。函数完成后,返回一些指针并将LastError设置为0。但是指针b指向无效内存。我尝试了4种不同的方式导入FindResource,结果都是一样的(b1、b2、b3、b4表示每个声明都是b)。我发现我需要先加载Library,让FindResource找到“某物”(a1=a2是两个相同的模块句柄,加载后正好指向内存中exe的开头,只是用不同的函数获取)。
我认为a(a=a1=a2)和b必须位于相同的内存空间中(偏移到模块开始?)。但是b和a的差值总是一样的16568。在十六进制编辑器中,我看到我的字符串大约在偏移量8000左右,并且在每个资源创建之后都会发生变化。我有可能出错的想法,但我不确定:

  • MAKELANGID(0,0)
    ~我知道0和0代表中立,我在某个地方读到关于
    *.mui
    文件的内容
  • 资源创建使资源破碎?实际上,两个资源编辑器在显示我的资源时都没有问题
  • 导入声明可能是错误的,但我已经尝试了很多种可能性,这些都是最好的
  • 资源需要打开/锁定/什么的
如何才能成功找到资源?我的代码中有bug吗?


公共静态类MyClass
{
[DllImport(“kernel32.dll”,CharSet=CharSet.Ansi,SetLastError=true)]
公共静态外部IntPtr LoadLibrary([Marshallas(UnmanagedType.LPStr)]字符串文件名);
[DllImport(“kernel32.dll”,CharSet=CharSet.Ansi,SetLastError=true)]
公共静态外部布尔自由库(IntPtr模块);
[DllImport(“kernel32.dll”,CharSet=CharSet.Ansi,SetLastError=true)]
公共静态外部IntPtr GetModuleHandle([Marshallas(UnmanagedType.LPStr)]字符串文件名);
[DllImport(“kernel32.dll”)]
公共静态外部IntPtr BeginUpdateResource([Marshallas(UnmanagedType.LPStr)]字符串文件名,bool deleteExistingResources);
[DllImport(“kernel32.dll”)]
公共静态外部bool UpdateResource(IntPtr资源,[MarshalAs(UnmanagedType.LPStr)]字符串类型,[MarshalAs(UnmanagedType.LPStr)]字符串名称,ushort语言,IntPtr数据,uint数据大小);
[DllImport(“kernel32.dll”)]
公共静态外部bool EndUpdateResource(IntPtr资源,bool丢弃);
[DllImport(“kernel32.dll”,CharSet=CharSet.Ansi,EntryPoint=“FindResource”,SetLastError=true)]
公共静态外部IntPtr FindResource1(IntPtr模块,[MarshalAs(UnmanagedType.LPStr)]字符串名称,[MarshalAs(UnmanagedType.LPStr)]字符串类型;
[DllImport(“kernel32.dll”,CharSet=CharSet.Ansi,EntryPoint=“FindResource”,SetLastError=true)]
公共静态外部IntPtr FindResource2(IntPtr模块、IntPtr名称、IntPtr类型);
[DllImport(“kernel32.dll”,CharSet=CharSet.Ansi,EntryPoint=“FindResource”,SetLastError=true)]
公共静态外部IntPtr FindResource3(IntPtr模块,[In,marshallas(UnmanagedType.LPStr)]字符串名称,[In,marshallas(UnmanagedType.LPStr)]字符串类型;
[DllImport(“kernel32.dll”,CharSet=CharSet.Ansi,EntryPoint=“FindResource”,SetLastError=true)]
公共静态外部IntPtr FindResource4(IntPtr模块,字符串lpName,字符串lpType);
公共静态ushort MAKELANGID(ushort原始语言,ushort子语言)
{
return Convert.ToUInt16((subLanguage返回一个句柄,而不是指向资源的指针;获取数据还需要几个步骤。您需要先获取一个句柄,然后获取指向实际资源字节的指针


据我所知,这是旧16位时代的遗留问题。

没错,谢谢!问题解决了!只有SizeofResource的提示丢失了!只需要把它挖出来。
public static class MyClass
{
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string fileName);
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    public static extern bool FreeLibrary(IntPtr module);
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    public static extern IntPtr GetModuleHandle([MarshalAs(UnmanagedType.LPStr)] string filename);

    [DllImport("kernel32.dll")]
    public static extern IntPtr BeginUpdateResource([MarshalAs(UnmanagedType.LPStr)] string filename, bool deleteExistingResources);
    [DllImport("kernel32.dll")]
    public static extern bool UpdateResource(IntPtr resource, [MarshalAs(UnmanagedType.LPStr)] string type, [MarshalAs(UnmanagedType.LPStr)] string name, ushort language, IntPtr data, uint dataSize);
    [DllImport("kernel32.dll")]
    public static extern bool EndUpdateResource(IntPtr resource, bool discard);

    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, EntryPoint = "FindResource", SetLastError = true)]
    public static extern IntPtr FindResource1(IntPtr module, [MarshalAs(UnmanagedType.LPStr)]string name, [MarshalAs(UnmanagedType.LPStr)] string type);
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, EntryPoint = "FindResource", SetLastError = true)]
    public static extern IntPtr FindResource2(IntPtr module, IntPtr name, IntPtr type);
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, EntryPoint = "FindResource", SetLastError = true)]
    public static extern IntPtr FindResource3(IntPtr module, [In, MarshalAs(UnmanagedType.LPStr)]string name, [In, MarshalAs(UnmanagedType.LPStr)] string type);
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, EntryPoint = "FindResource", SetLastError = true)]
    public static extern IntPtr FindResource4(IntPtr module, string lpName, string lpType);

    public static ushort MAKELANGID(ushort primaryLanguage, ushort subLanguage)
    {
        return Convert.ToUInt16((subLanguage << 10) | primaryLanguage);
    }

    private static void test()
    {
        string filename1 = "MyApp.exe";
        string filename2 = "MyApp2.exe";
        //if (!File.Exists(filename2))
        {
            // creating resource: name = TEST, type = SYSO, lang-id = neutral
            File.Copy(filename1, filename2, true);
            IntPtr res = BeginUpdateResource(filename2, false);
            string s = "aaahello world";
            UpdateResource(res, "SYSO", "TEST", MAKELANGID(0, 0), Marshal.StringToHGlobalAnsi(s), (uint) (s.Length));
            EndUpdateResource(res, false);
        }
        // find resource
        IntPtr a1 = LoadLibrary(filename2);
        IntPtr a2 = GetModuleHandle(filename2);
        IntPtr hInstance = Marshal.GetHINSTANCE(typeof(MyClass).Module);
        if (a1 == a2)
            Console.WriteLine("a1 = a2 = " + a2 + ", hInstance: " + hInstance);
        else
            Console.WriteLine(a1 + " != " + a2);

        for (int i = 0; i < 10; i++)
            Console.WriteLine("." + Marshal.ReadByte(a2 + i));

        IntPtr b1 = FindResource1(a2, "TEST", "SYSO");
        IntPtr b2 = FindResource2(a2, Marshal.StringToHGlobalAnsi("TEST"), Marshal.StringToHGlobalAnsi("SYSO"));
        IntPtr b3 = FindResource3(a2, "TEST", "SYSO");
        IntPtr b4 = FindResource4(a2, "TEST", "SYSO");

        Console.WriteLine(" -> res: " + b1 + ", " + (b1.ToInt32() - a2.ToInt32()) + ", " + Marshal.PtrToStringAnsi(b1));
        Console.WriteLine(" -> res: " + b2 + ", " + (b2.ToInt32() - a2.ToInt32()) + ", " + Marshal.PtrToStringAnsi(b2));
        Console.WriteLine(" -> res: " + b3 + ", " + (b3.ToInt32() - a2.ToInt32()) + ", " + Marshal.PtrToStringAnsi(b3));
        Console.WriteLine(" -> res: " + b4 + ", " + (b4.ToInt32() - a2.ToInt32()) + ", " + Marshal.PtrToStringAnsi(b4));

        for (int i = 0; i < 10; i++)
            Console.WriteLine("." + Marshal.ReadByte(b1 + i));
    }

    [STAThread]
    public static void Main()
    {
        test();
        Console.ReadKey();
    }
}