2

We have an automation scenario (mostly MSUIA) between 2 application, the target is 32bit, my app (the automating one) is 64bit, on a 64bit win7. Some of the information that needs to be shared has to be accessed through direkt Win SDK calls (like SendMessage, GetFocus and the like).

From my understanding now, Win64 and 32 Subsystem are completely separate, so any such kind of interaction should fail straight away (trying to e. g. access parts of the 32bit app through a 64bit app). Strangely enough though, most stuff seems to work fine. So there seems to be some kind of marshalling/whatever internally.

I have run into a few scenarios now, though, where there seem to be problems with the way I define my p/invoke functions. I have declared them the "official MS way" with using IntPtr whenever something might change size (also using the great http://www.pinvoke.net/default.aspx/ site), so since I force my .net app to be 64bit (using compile switches), they should be compiled for 64bit using the 64bit versions of the dll.

The strange thing now is that when using those calls to access the 32bit app (like for example GetWindowText which actually reads from the other process' memory) those calls seem to work fine. But. Subsequent MSUIA calls seem to randomly fail.

If I (wrongly) declare a 32bit signature for the p/invoke calls even though compiling to 64bit, everything is running fine.

To me, this makes no sense.

Cleanest solution probably is to compile my app to 32bit as well (or same as target app), still.. I would be grateful for any insights into this one.

Andreas Reiff
  • 7,961
  • 10
  • 50
  • 104
  • Something wrong with your pinvoke declaration most likely, it can unbalance the stack pointer and cause subsequent code to go pretty haywire. Debug + Windows + Registers and verify that the value of ESP is the same before and after the call. There's an MDA for it, make sure you didn't disable pInvokeStackImbalance – Hans Passant Apr 27 '12 at 00:27

1 Answers1

2

A 64 bit process can only execute 64 bit code. A 32 bit process can only execute 32 bit code. Now, the operating system kernel, for a 32 bit process, will switch into 64 bit mode for any kernel level system calls. But that's really the business of the operating system.

When you call GetWindowText, from a 64 bit process, you are calling the 64 bit user32.dll. When you call from a 32 bit process, you are calling hte 32 bit user32.dll. It doesn't matter whether the target window is in a 32 or 64 bit process, what matters is the bitness of the executing code.

The section of your question which talks about 32 bit versions of the p/invoke signatures doesn't make much sense to me. I can't really say more without seeing any code.

You wonder whether or not you need to compile your app for 32 bit. I doubt it. You are doing automation of a different process. It is perfectly normal for a 32 bit process to automate a 64 bit process, and vice versa.

What you can't mix is different bitness modules in the same process. You can't load a 32 bit DLL from a 64 bit executable. And vice versa. But you are not doing that, which means that you can compile your app for either 32 bit or 64 bit.

Now, having said that you can use either 32 or 64 bit process, I would recommend that you target 32 bit. The reason being it makes your deployment simpler since you have just a single version of the app. Yes, you could use AnyCPU, but why bother. If you don't need 64 bit process then it is simpler to stick to the lowest common denominator.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks a lot for the insight! Actually, I found out I had other problems that only became visible in a version where I had chagned too much.. Still, my programs runs fine with different signatures. I will have to investigate this. Maybe things just happen to work out nicely, like the paramter I need is the first and only 4 bytes are used or something like that.. (it certainly does not crash) Also, I wonder.. sometimes I need to register in-process-memory from another process in order to get a result for SendMessage. Is even that not a problem between 32 and 64 bit? Actually, it worked fine. – Andreas Reiff Apr 27 '12 at 13:32
  • 1
    In-process memory and SendMessage? Depends on the message. Some messages will marshal your memory across the process boundary. It depends. No single generic answer. – David Heffernan Apr 27 '12 at 14:03
  • Thanks again! How to find out? Can I access anything from any application since it gets properly converted internally? Like if I call a function like VirtualAllocEx that allocated memory in another application, is it certain that I can handle the result (like if a 32bit app allocs mem in a 64bit app)? (As an explanation: that is then used to store the return value of some SendMessage.) – Andreas Reiff May 10 '12 at 13:45