Sending keystrokes to a background process (hidden)

Get help with using AutoHotkey and its commands and hotkeys
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Sending keystrokes to a background process (hidden)

15 Nov 2018, 12:04

Greetings,

I have been trying to figure something out, on my own, for about a month now. Recently I have figured out why it won't work, but can't figure out how to make it work.

OBS Studio(Open Broadcast Software--- streaming program) has the ability to minimize to system tray when started, and minimize to the system tray instead of taskbar.

I need it to do this, as it runs completely in the background.

But, I need it to send one set of keystrokes to it, using AHK (Either on a schedule, or when it launches).

WinActivate ahk_class Qt5QWindowIcon is the window class when its maximized, and it will receive AHK commands.

But... when it is minimized to the system tray it shows up in Task Manager as a Background process (obs64.exe - on my machine)... and the window class Qt5QWindowIcon seems to be irrelevant.

So, how does one go about sending something to the windows process, which is hidden differently than just one window behind another, or something sitting in the taskbar?

Thanks

Macnrayna
oif2003
Posts: 212
Joined: 17 Oct 2018, 11:43
GitHub: oif2003

Re: Sending keystrokes to a background process (hidden)

15 Nov 2018, 12:51

I'm no expert at this but these are the things I would try:
1) See if enabling DetectHiddenWindows helps
2) Try other ways of hiding the window, ie: give it the WS_EX_TOOLWINDOW style, play with transparency settings, or move/resize it to hide it
3) Briefly open the window to send a burst of keystrokes
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 13:18

Thanks oif2003
I have played around with your suggestions as well as some other ideas of my own.

Right now WinShow seems to be the most successful option. It sends the command to OBS, even when its hidden, BUT opens the wrong window. It opens a window called Output Timer, not the one I want called MultiView (Windowed). Is there a way to ensure the command goes not just to the ahk_class, but with the correct result?

#Persistent

#F8::
WinShow, ahk_class Qt5QWindowIcon ;this will call for the Output Timer with or without the keystrokes below.

sleep, 100

Send, {alt}
Send, {v}
Send, {down}
Send, {down}
Send, {down}
Send, {down}
Send, {down}
Send, {down}
Send, {enter}

Sleep 100

return
User avatar
Maestr0
Posts: 52
Joined: 05 Dec 2013, 17:43

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 13:25

I think you're looking for ControlSend: https://autohotkey.com/docs/commands/ControlSend.htm

Just to give you a quick example, add the following to a new script and run it.
It should start notepad.exe but minimized.
Press F8.
Activate notepad and see the text that is entered.

Code: Select all

#persistent

run, %A_windir%\notepad.exe, , min

F8::
	ControlSend, Edit1, This is filled by ControlSend, ahk_class Notepad ahk_exe notepad.exe
	WinActivate ahk_class Notepad ahk_exe notepad.exe
return
oif2003
Posts: 212
Joined: 17 Oct 2018, 11:43
GitHub: oif2003

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 14:03

Hi, try what Maestr0 said, and maybe use WindowSpy to help you target the specific control (in his example it was "Edit1").
Another option is to explore WinMenuSelectItem: https://www.autohotkey.com/docs/command ... ctItem.htm
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 15:23

Thanks for the input. I see what you are suggesting, and will play with it.

Forgive a noob question, but if %A_windir% is "C:\Windows"

What would "C:\Program Files (x86)\PROGRAM NAME" be?

Because putting a shortcut in C:\Windows doesn't seem to work.
oif2003
Posts: 212
Joined: 17 Oct 2018, 11:43
GitHub: oif2003

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 15:27

A_ProgramFiles: https://www.autohotkey.com/docs/Variabl ... ogramFiles
The Program Files directory (e.g. C:\Program Files or C:\Program Files (x86)). This is usually the same as the ProgramFiles environment variable.

On 64-bit systems (and not 32-bit systems), the following applies:

If the executable (EXE) that is running the script is 32-bit, A_ProgramFiles returns the path of the "Program Files (x86)" directory.
For 32-bit processes, the ProgramW6432 environment variable contains the path of the 64-bit Program Files directory. On Windows 7 and later, it is also set for 64-bit processes.
The ProgramFiles(x86) environment variable contains the path of the 32-bit Program Files directory.
so essentially, %A_ProgramFiles%\ProgramFolder\Program.exe, or you can always use the full path
User avatar
jeeswg
Posts: 6373
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 15:38

If multiple windows exist with the same class, perhaps the window title or window style/ex. style will help you identify the correct window. I.e. you're looking for some unique criteria to help identify the window.

Code: Select all

q:: ;check window info
DetectHiddenWindows, On
;WinGet, vWinList, List, ahk_class Notepad
WinGet, vWinList, List, ahk_class Qt5QWindowIcon
vOutput := ""
Loop, % vWinList
{
	hWnd := vWinList%A_Index%
	WinGetTitle, vWinTitle, % "ahk_id " hWnd
	;WinGetClass, vWinClass, % "ahk_id " hWnd
	;WinGet, vPID, PID, % "ahk_id " hWnd
	WinGet, vWinStyle, Style, % "ahk_id " hWnd
	WinGet, vWinExStyle, ExStyle, % "ahk_id " hWnd
	vWinStyle := Format("0x{:08X}", vWinStyle)
	vWinExStyle := Format("0x{:08X}", vWinExStyle)
	vOutput .= vWinTitle "|" vWinStyle "|" vWinExStyle "`r`n"
}
MsgBox, % vOutput
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 15:52

oif2003 wrote:
03 Dec 2018, 15:27
A_ProgramFiles: https://www.autohotkey.com/docs/Variabl ... ogramFiles
The Program Files directory (e.g. C:\Program Files or C:\Program Files (x86)). This is usually the same as the ProgramFiles environment variable.

On 64-bit systems (and not 32-bit systems), the following applies:

If the executable (EXE) that is running the script is 32-bit, A_ProgramFiles returns the path of the "Program Files (x86)" directory.
For 32-bit processes, the ProgramW6432 environment variable contains the path of the 64-bit Program Files directory. On Windows 7 and later, it is also set for 64-bit processes.
The ProgramFiles(x86) environment variable contains the path of the 32-bit Program Files directory.
so essentially, %A_ProgramFiles%\ProgramFolder\Program.exe, or you can always use the full path
Like this:
run, %A_ProgramFiles%\obs-studio\bin\64bit\obs64.exe, , min

?
I get an error message on this line when I try to reload AHK
oif2003
Posts: 212
Joined: 17 Oct 2018, 11:43
GitHub: oif2003

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 15:56

Macnrayna wrote:
03 Dec 2018, 15:52

Like this:
run, %A_ProgramFiles%\obs-studio\bin\64bit\obs64.exe, , min

?
I get an error message on this line when I try to reload AHK
Don't use it with the variable and use the full path instead. Perhaps your AHK is 32bit and it is pointing you to the (x86) folder.
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 16:52

jeeswg wrote:
03 Dec 2018, 15:38
If multiple windows exist with the same class, perhaps the window title or window style/ex. style will help you identify the correct window. I.e. you're looking for some unique criteria to help identify the window.

Code: Select all

q:: ;check window info
DetectHiddenWindows, On
;WinGet, vWinList, List, ahk_class Notepad
WinGet, vWinList, List, ahk_class Qt5QWindowIcon
vOutput := ""
Loop, % vWinList
{
	hWnd := vWinList%A_Index%
	WinGetTitle, vWinTitle, % "ahk_id " hWnd
	;WinGetClass, vWinClass, % "ahk_id " hWnd
	;WinGet, vPID, PID, % "ahk_id " hWnd
	WinGet, vWinStyle, Style, % "ahk_id " hWnd
	WinGet, vWinExStyle, ExStyle, % "ahk_id " hWnd
	vWinStyle := Format("0x{:08X}", vWinStyle)
	vWinExStyle := Format("0x{:08X}", vWinExStyle)
	vOutput .= vWinTitle "|" vWinStyle "|" vWinExStyle "`r`n"
}
MsgBox, % vOutput
return

Thanks. I get this:
windowstyle.PNG
windowstyle.PNG (9.78 KiB) Viewed 1164 times
If I am correct in my understanding of what that is to provide, It does list Output timer there, which is specifically what I DON'T want. Then I would assume that WinShow is calling for the wrong part of the program... so what do I do now please?
User avatar
jeeswg
Posts: 6373
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 17:01

- I see 4 windows listed. Do any of those 4 window descriptions match the window you want to send key presses to?
- If so, then when vWinTitle has the right window title, hWnd has the correct window handle. And you could use that hWnd with ControlSend, WinActivate or some other AutoHotkey command/function.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 17:29

Yes the second line is the one I want... OBS Studio...

So, what do I do next?

Let's say I want to continue to use WinShow (it has given me the most success thus far) with the following...

Persistent

#F8:: WinShow, ahk_class Qt5QWindowIcon ;do I change this here to represent the windows handle instead of the ahk_class?


sleep, 100

Send, {alt}
Send, {v}
Send, {down}
Send, {down}
Send, {down}
Send, {down}
Send, {down}
Send, {down}
Send, {enter}
User avatar
jeeswg
Posts: 6373
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 17:33

This should work. 'start-of-title ahk_class class'.

Code: Select all

;hotkey one-liner (does one action)
#F8:: WinShow, OBS Studio ahk_class Qt5QWindowIcon

Code: Select all

;hotkey multi-liner
#F8::
WinShow, OBS Studio ahk_class Qt5QWindowIcon
Sleep, 100
Send, !v
Send, {down 6}
Send, {enter}
return
Btw there might be a bit of a learning curve re. using Acc, but it can be useful for interacting with OBS Studio.
obs studio start and record - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 18#p122818
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

03 Dec 2018, 17:52

well that's close... it pops it from a background process (hidden in the system tray) onto the taskbar. But it is a weird blank white screen (below) and not what it's supposed to be. It's like it only half loads, and therefore won't receive the keystrokes. It will fix itself if I try to minimize. It pops down and then back up again normally... very strange.

It was also doing that when it displayed the Output Timer window, but I didn't give it much thought as that wasn't my intent to begin with.


This is what I get
Capture1 (Custom).PNG
Capture1 (Custom).PNG (20.02 KiB) Viewed 1147 times
This is what its supposed to look like
Capture2 (Custom).PNG
Capture2 (Custom).PNG (34.14 KiB) Viewed 1147 times
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

04 Dec 2018, 12:39

Building on my last reply... I can modify the hot key to retrieve another hidden-on-system-tray program, and it works perfectly.

So... any thoughts on why with OBS it shows up as a blank white window?

jeeswg wrote:
03 Dec 2018, 17:33
This should work. 'start-of-title ahk_class class'.

Code: Select all

;hotkey one-liner (does one action)
#F8:: WinShow, OBS Studio ahk_class Qt5QWindowIcon

Code: Select all

;hotkey multi-liner
#F8::
WinShow, OBS Studio ahk_class Qt5QWindowIcon
Sleep, 100
Send, !v
Send, {down 6}
Send, {enter}
return
Btw there might be a bit of a learning curve re. using Acc, but it can be useful for interacting with OBS Studio.
obs studio start and record - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 18#p122818
User avatar
jeeswg
Posts: 6373
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Sending keystrokes to a background process (hidden)

04 Dec 2018, 12:53

- You could try WinShow and WinActivate together. Possibly WinRestore.
- You could try something like this. For many programs, if only one instance is allowed, trying to run it again shows the window.

Code: Select all

vPath := "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\OBS Studio\OBS Studio (32bit).lnk"
;vPath := "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\OBS Studio\OBS Studio (64bit).lnk"
Run, % vPath
- Which version of OBS Studio are you using? Mine doesn't have a tray icon, although it's from around mid-2016.
- Other ideas are: is there any command-line option to reopen an existing window, are there any menu items you could use, on the menu bar or alt-space menu, finding out information about the tray icon (what message is sent to what window) and replicating that. [EDIT: Perhaps the tray icon approach could work, I'm doubtful about the other two.]
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

04 Dec 2018, 13:03

I'm on version 22 (most recent) which allows for it to disappear into the tray on launch. This is helpful as I don't always know who will be at the computer and this prevents accidents from happening ie. someone exiting the program, etc. It is found under settings/System Tray
Macnrayna
Posts: 20
Joined: 18 Oct 2016, 19:20
GitHub: Michael

Re: Sending keystrokes to a background process (hidden)

04 Dec 2018, 13:13

OK, this is working!!!!
But, it seems a bit redundant.... up... down... up again then the keystrokes.

Is that just the way it has to be sometimes?

#F8::

WinShow, OBS ahk_class Qt5QWindowIcon
WinRestore, OBS ahk_class Qt5QWindowIcon
WinMinimize, OBS ahk_class Qt5QWindowIcon

Sleep, 100
Send, !v
Send, {down 6}
Send, {enter}
return
User avatar
jeeswg
Posts: 6373
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Sending keystrokes to a background process (hidden)

04 Dec 2018, 14:57

- OK I have a solution.

Code: Select all

q:: ;obs studio - toggle hide/show window
DetectHiddenWindows, On
PostMessage, 0x8065, 0, 0x400,, ahk_class QTrayIconMessageWindowClass ;WM_USER := 0x400
return

w:: ;obs studio - hide window
DetectHiddenWindows, On
WinGet, hWnd, ID, OBS ahk_class Qt5QWindowIcon
if DllCall("user32\IsWindowVisible", Ptr,hWnd)
	PostMessage, 0x8065, 0, 0x400,, ahk_class QTrayIconMessageWindowClass ;WM_USER := 0x400
return

e:: ;obs studio - show window
DetectHiddenWindows, On
WinGet, hWnd, ID, OBS ahk_class Qt5QWindowIcon
if !DllCall("user32\IsWindowVisible", Ptr,hWnd)
	PostMessage, 0x8065, 0, 0x400,, ahk_class QTrayIconMessageWindowClass ;WM_USER := 0x400
return
- I had the same problem as you when doing WinShow, the window was initially transparent, if you 'jogged' it enough, it would display properly, although I didn't stick around to find the best 'jog'.
- By using the example for JEE_TBGetText, here:
GUIs via DllCall: text functions (get/set internal/external control text) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=40514
I was able to get tray icon info. Leading me to believe that this line:
PostMessage, 0x8065, 0, X,, ahk_class QTrayIconMessageWindowClass
would allow me to show the window, if I could figure out X.
- Typically a tray icon will have an hWnd and a uMsg associated with it, you send the uMsg and another number to the hWnd that should trigger an action. By investigating the properties of the window with that hWnd, you may be able to find out some consistent info about it for identification purposes e.g. its class name.
- Individual/multiple uses of the usual suspect numbers didn't appear to work e.g.
WM_LBUTTONDOWN := 0x201
WM_LBUTTONUP := 0x202
WM_LBUTTONDBLCLK := 0x203
WM_RBUTTONDOWN := 0x204
WM_RBUTTONUP := 0x205
WM_RBUTTONDBLCLK := 0x206
- So I tried brute force, looking to see if any number worked to show the window, and WM_USER := 0x400 appeared to work.
- Methods to get the menu item IDs for use with WM_COMMAND didn't work, in case anyone's able to figure something out.
- I couldn't find any reference to 0x8065 (32869) in the OBS source code. Also, I found references to the menu item IDs in the source code, but not specific numbers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: songdg and 127 guests