Get filename of x64 module from 32bit process

N

nagar

Hi,

I have a 32bit .NET process running in a 64bit environment (Windows 7
Ultimate 64bit).
I need to get the filename of the currently active application. Is
there a way to do that?
I was using GetModuleEx but it fails (I get a path with strange
characters).
Thank you.
Andrea
 
N

nagar

Thanks for the reply.
My application has been marked to run explicitly as a 32bit app (I've
compiled it with the x86 flag).
I need to get the exe name of the application that currently has the
focus which may not be my application but another app (that maybe is a
native 64 bit application).

Here's the code I use that I'm having problems with (it returns the
name of the exe which is the owner of the window handle but on Windows
7 64bit I got strange characters instead of the filename).

Here's the code with the two external declarations. Is there anything
wrong here?

public static string GetProcessPathFromWindowHandle(IntPtr hWnd) {

string filename = string.Empty;
uint pid=0;
Unmanaged.GetWindowThreadProcessId(hWnd, out pid);

//error in Win64: returns strange characters for Win64
files
const int nChars = 1024;
StringBuilder filenameBuffer = new StringBuilder(nChars);
IntPtr hProcess = Unmanaged.OpenProcess(1040, 0, pid);
Unmanaged.GetModuleFileNameEx(hProcess, IntPtr.Zero,
filenameBuffer, nChars);
Unmanaged.CloseHandle(hProcess);

filename = filenameBuffer.ToString();
return filename;
}

[DllImport("psapi.dll")]
public static extern uint GetModuleFileNameEx(IntPtr hProcess,
IntPtr hModule, [Out] StringBuilder lpBaseName, [In]
[MarshalAs(UnmanagedType.U4)] int nSize);

[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr
hWnd, out uint lpdwProcessId);

What's wrong here? How shall I modify those declarations so that I
make it work on Windows 7 64bit?

Thanks a lot.
Andrea
 
J

Jeroen Mostert

I have a 32bit .NET process running in a 64bit environment (Windows 7
Ultimate 64bit).

This is possible, but are you sure? By default .NET applications will run as
64-bit on 64-bit operating systems. They have to be explicitly marked as
running as 32-bit only to override this behavior.
I need to get the filename of the currently active application. Is
there a way to do that?

Define "currently active application".
I was using GetModuleEx but it fails (I get a path with strange
characters).

I take it you mean GetModuleFileNameEx(). In all likelihood your P/Invoke
declarations are incorrect.

To get the name of the entry assembly from within the application itself,
you can simply use Assembly.GetEntryAssembly().Location. To get the module
names of other processes, use Process.GetProcesses() and inspect the
..MainModule.FileName property.

There should be no need to P/Invoke. If you think there is, make your
scenario more explicit.
 
J

Jeroen Mostert

Thanks for the reply.
My application has been marked to run explicitly as a 32bit app (I've
compiled it with the x86 flag).
I need to get the exe name of the application that currently has the
focus which may not be my application but another app (that maybe is a
native 64 bit application).

Here's the code I use that I'm having problems with (it returns the
name of the exe which is the owner of the window handle but on Windows
7 64bit I got strange characters instead of the filename).

Here's the code with the two external declarations. Is there anything
wrong here?
Well, one rather prominent thing.
public static string GetProcessPathFromWindowHandle(IntPtr hWnd) {

string filename = string.Empty;
uint pid=0;
Unmanaged.GetWindowThreadProcessId(hWnd, out pid);

//error in Win64: returns strange characters for Win64
files
const int nChars = 1024;
StringBuilder filenameBuffer = new StringBuilder(nChars);
IntPtr hProcess = Unmanaged.OpenProcess(1040, 0, pid);

You're not checking for errors. If OpenProcess() fails, the return value is
NULL.

Declare OpenProcess() in its DllImport with SetLastError = true and check
the return value. If it's IntPtr.Zero, use "throw new Win32Exception()" to
see the problem.
Unmanaged.GetModuleFileNameEx(hProcess, IntPtr.Zero,
filenameBuffer, nChars);

You are not checking errors here either. If hProcess is invalid,
GetModuleFileNameEx() will do nothing and the buffer that's marshalled back
will contain random garbage. This is probably what you're seeing.
 
N

nagar

Thanks for the suggestion.
I'll try that and see what gets reported. My doubt, however, is that
this thing is working properly on Windows XP 32bit and failing in
Windows 7 64bit. I wonder if I can call the OpenProcess and get the
required info if the target process is running in native 64 bit mode
while my application is in 32bit mode.

I'll get back in this thread as I get what error gets reported.
I really appreciate your help.
Andrea
 
J

Jeroen Mostert

Thanks for the suggestion.
I'll try that and see what gets reported. My doubt, however, is that
this thing is working properly on Windows XP 32bit and failing in
Windows 7 64bit.

Windows 7, like its predecessor Vista, considerably tightened up security. I
would sooner think the problem lies with that than in the 32/64-bit
transition.
I wonder if I can call the OpenProcess and get the required info if the
target process is running in native 64 bit mode while my application is
in 32bit mode.
That's easy enough to check -- isolate this bit of code and mark your .NET
application as 64-bit instead. If it then works, you know the problem is a
32/64-bit one.
 
D

DashGir

I tried to use the Platform=x86 switch to compile as 32 bit. But it did not
work. My solution has several projects and all of them are set as "Any CPU".
I had to change them to "x86" for the compile switch to work.
Do you know how to find out if the application running is a 32 bit or 64 bit
process?
Is there a way to set the projects to "Any CPU" and only use the Compile
switch to build as x86?

thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top