0

I am currently working on a programmable keyboard, based on an Arduino. The C# program gets the information which key is pressed via USB. Until now I am able to open programs, using shortcuts, ...

As an addition I want to have different key-bindings for different programs. To get this working I have to get a specific detail from the active program, like the name of the exe file.

While searching I have found out, that I can get the active window with the GetActiveWindow function and I know, that I have to use another Windows function, but I haven't found out which one.

I was able to get the header text of the window, but this text was for example different for each open Word document, so I couldn't use this.

Anyone have a clue which function I can use, to get something specific to compare with an if statement, like this:

string activeProgram;
...
if(activeProgram=="Word"){...}
else if(activeProgram=="Chrome"){...}
gre_gor
  • 6,669
  • 9
  • 47
  • 52
Schiep
  • 3
  • 1

1 Answers1

1

Since you are using GetActiveWindow you have a Window Handle (hWnd).

You can use it to get a Process Id by calling GetWindowThreadProcessId.

This is the P/Invoke declaration:

[DllImport("user32.dll", SetLastError=true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);

Once you have a Process Id, you need to find the executable.

If you were to continue using the windows API... you can do that with GetModuleFileNameEx, GetProcessImageFileName or QueryFullProcessImageName. You would need to use OpenProcess to get a Process Handle (hProcess).

Although, there is no need to. Once you have a Process Id you can get the executable file using Process:

var process = Process.GetProcessById((int)processId);
var fileName = process.MainModule.FileName;

Note: the security restriction still apply. Your program will need to have the required privileges to read the other process and get the file name.


With that, you can get the main executable file of the process that created the active window. Although, what if a malicious user has renamed an executable something else to trick your program? - Bonus chatter: how to check if a file has a digital signature.

Theraot
  • 31,890
  • 5
  • 57
  • 86
  • The code is working so far and i get the full path of my file (this is something i can really good work with, thank you), but the problem is, when i want to get the name of another window, i get an Win32 exception, because i can´t access a 64bit process with a 32bit process. Can i make my own file a 64bit program? Or is there another way? – Schiep Jun 01 '17 at 18:56
  • @Schiep first make sure you are not casting between IntPtr and int. You need to declare [`GetActiveWindow` to return IntPtr](http://www.pinvoke.net/default.aspx/user32.getactivewindow). Second, you may need to configure compile targets for 32 bits and 64 bits (under Build -> Configuration Manager). See [64-bit Applications](https://msdn.microsoft.com/en-us/library/ms241064.aspx) on msdn. The article [Considerations for porting existing .NET (C#) applications to 64-bit](https://www.ibm.com/support/knowledgecenter/SSGSMK_7.1.1/development_sym/app_net_port_64bit.html) may help (ignore Symphony). – Theraot Jun 01 '17 at 19:16