2

I am developing a c# application that extract a cab file from a setup package.

to do that I am using LoadLibrary. this is the pinvoke C# signature.

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

The above code works fine when compiling the project to x86, but if I compile it to anycpu it fails, and the last win32 error is:

"%1 is not a valid Win32 application"

I tried to use IntPtr insted of a string, and also to use dfferent charset but nothing worked.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
user844541
  • 2,868
  • 5
  • 32
  • 60
  • 1
    I think I found the answer in here: http://technet.microsoft.com/en-us/library/cc782541(v=ws.10).aspx it seems that I must run a separate process. – user844541 Jun 17 '13 at 11:20
  • Related http://pinvoke.net/default.aspx/kernel32/LoadLibrary.html – PeskyGnat Jun 17 '13 at 11:22
  • You could also force your application, if compiled using AnyCPU, to run in 32-bit mode as this article describes http://lostechies.com/gabrielschenker/2009/10/21/force-net-application-to-run-in-32bit-process-on-64bit-os/ – PeskyGnat Jun 17 '13 at 11:29
  • @PeskyGnat That seems pointless here. Since the asker is already compiling the app and has control of the target, the right way to force 32 bit is to target x86. – David Heffernan Jun 17 '13 at 11:38
  • I agree, if there is no requirement to use anycpu, then x86 is the way to go – PeskyGnat Jun 17 '13 at 11:44
  • @PeskyGnat I thought that you should target anycpu unless there is a requirement to use x86... anyhow this code is part of a huge project that is compiled to anycpu... – user844541 Jun 17 '13 at 12:33

1 Answers1

4

LoadLibrary works fine. The problem is that you are attempting to load a 32 bit DLL into a 64 bit process. This cannot be done and the error message that you quote is the result of attempting to mix modules with non-matching bitness.

The problem is not in the p/invoke signature for LoadLibrary, rather the call to LoadLibrary that is not shown in the question. That call is resulting in an attempt to load a 32 bit DLL into your 64 bit process. Unless you have 64 bit versions of all the native DLLs that you load, you'll need to stick to x86.

As an aside there's really no point in using CharSet.Ansi for this function. Since .net use UTF-16 text natively you would be far better off using CharSet.Unicode, avoiding any character set conversions and making sure that your program can support Unicode file names.

Update

In the comments you ask if it is possible to load a 32 bit DLL from a 64 bit process for the purpose of extracting resources. It is possible, but not with LoadLibrary. You need to call LoadLibraryEx passing LOAD_LIBRARY_AS_DATAFILE.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks, when i worte the question I thought the problem is with the signature, but after I looked into the error code I understood this is a loading issue. do you know if there is a 64 bit version of Kernel32? – user844541 Jun 17 '13 at 11:41
  • My mistake :) the problem is that the .exe I am trying to load is compiled to 32 bit. – user844541 Jun 17 '13 at 11:47
  • As I said, the issue is not in the resolution of `LoadLibrary`. There is of course a 64 bit version of `kernel32` and every process includes it. The call to `LoadLibrary` is made correctly. But the module that you are trying to load, the module whose name you pass to `LoadLibrary` does not match the bitness of your managed process. – David Heffernan Jun 17 '13 at 11:49
  • :( so do you know how can I extract the cab file that is in the .exe without using loadResource? – user844541 Jun 17 '13 at 12:06
  • I do indeed know how, and have added that to the answer. I think I've answered both your questions now. – David Heffernan Jun 17 '13 at 12:11
  • OK, but the section marked update is not part of the question, if I am being picky. – David Heffernan Jun 17 '13 at 12:20
  • I can create another question if you want :) Thank you so so much!! I worked for hours on writing a lib that extracts cab from .exe and then extract the files from the cab, and only after I finished I remembered to change the target to anycpu. You saved my life :) – user844541 Jun 17 '13 at 12:27
  • I'm not fussed about creating another question. I'm pleased that your problems are solved. – David Heffernan Jun 17 '13 at 12:28