OK, with WMIC as for prcessname-based call and some other improvements here is my final solution as a ready-to-use binary download:
https://github.com/Dragodraki/BringExeToFront
Hope, that helps somebody else in the future.
Announcement
Collapse
No announcement yet.
SetForegroundWindow by PID
Collapse
X
-
Maybe, but I didn't focus on that one
In the meantime I get another solution with wmic... it's slow but seems to work:
Call_ProcessName:
StrCpy $2 ""
searchnamecontinue:
FindWindow $1 "" "" "" $2
StrCpy $2 $1
${If} $1 P<> 0
System::Call 'USER32::GetWindowThreadProcessId(p$1,*i0r3)'
System::Call 'USER32::IsWindowVisible(p $1)i.r4'
System::Call 'USER32::GetWindowText(p $1, t ""r5, i ${NSIS_MAX_STRLEN})'
${If} $5 != ""
${AndIf} $4 <> 0
nsExec::ExecToStack "wmic process where $\"name like '$ProcessID' and ProcessID like '$3'$\" get processid
/format:$\"$PLUGINSDIR\${XlsSheet}$\""
Pop $0
Pop $7
${StrRep} $7 $7 "processid=" ""
Push ' $7 '
Call Trim
Pop $8 ;$8 now contains the trimmed string.
${If} $3 == $8
;MessageBox MB_OK "Erkannt! PID: $3"
System::Call 'USER32::SetForegroundWindow(p$1)'
System::Call 'USER32::SwitchToThisWindow(p$1,i1)'
${EndIf}
${EndIf}
Goto searchnamecontinue
${EndIf}
Goto EndSearch
Leave a comment:
-
-
Seems to me you did not try very hard.
PHP Code:!include LogicLib.nsh
Function PSEnum
${If} $0 = $MyPid
DetailPrint "Found $1"
StrCpy $0 ""
${EndIf}
FunctionEnd
Section
GetFunctionAddress $0 PSEnum
PS::Enum $0
SectionEnd
Leave a comment:
-
-
Unfortunately, I tried already. Either they don't include retrieving process name or it simply don't work.
I managed to call a result via wmic, but I cant get it to display each line of the variable separately.
Leave a comment:
-
-
Those functions only work for the current process. https://stackoverflow.com/questions/...me-of-a-window
I'd say, use one of the process plug-ins, https://nsis.sourceforge.io/PS_plug-in etc.
Leave a comment:
-
-
Thank you - you code works like a charm now!
May I ask to help me one more time?
How can I compare the process name instead of the PID if the process name is known only?
Input (search): -Process name-
Output (found): -Process name- for "p $1"
I tried with GetWindowModuleFilename, GetModuleBaseName and several others too, but never get a result at all.
Leave a comment:
-
-
There is nothing stopping you from enumerating all windows if you don't know the title nor class. If your loop is infinite you have a bug somewhere.
PHP Code:!include LogicLib.nsh
Section
StrCpy $2 ""
loop:
FindWindow $1 "" "" "" $2
StrCpy $2 $1
${If} $1 P<> 0
System::Call 'USER32::IsWindowVisible(p $1)i.r4'
System::Call 'USER32::GetWindowText(p $1, t ""r5, i ${NSIS_MAX_STRLEN})'
${If} $5 != ""
${AndIf} $4 <> 0
DetailPrint "Visible window $1 has title $5"
${EndIf}
Goto loop
${EndIf}
SectionEnd
Leave a comment:
-
-
Yes, I don't know the title, so the query for PID is indeed necessary.
But if I try to leave the title blank (FindWindow $1 "" "" "" $2), it doesn't work - in this case the entry it shows does't fit (${If} $1 P<> 0 seems to fail) and it repeats the loop infinte.
So I have to retrieve the windotitle from pid before everything else... but how can I achieve this?
Leave a comment:
-
-
Not sure I understand. If you don't know the window title you can leave it as "" like my example.
If you know the title and the pid is part of it then you don't even need the loop
StrCpy $mypid ....
; if the title is "fooPIDbar"
FindWindow $1 "AquaKeyTest" "foo$mypidbar"
Leave a comment:
-
-
!include WinMessages.nsh
!include LogicLib.nsh
StrCpy $mypid "4128" ;example PID (ok) - later this should applied from command-line parameter
StrCpy $2 ""
loop:
FindWindow $1 "" "Aquakeytest" "" $2 ;Windowtitle (not ok) should be determined automatically from PID
StrCpy $2 $1
${If} $1 P<> 0
;${AndIf} $0 <> 0 ; PID
System::Call 'USER32::GetWindowThreadProcessId(p$1,*i0r3)'
;MessageBox MB_OK "mypid(Search)=$mypid und PID(Found)=$3"
${If} $3 = $mypid
System::Call 'USER32::SetForegroundWindow(p$1)'
System::Call 'USER32::SwitchToThisWindow(p$1,i1)'
${Else}
Goto loop
${EndIf}
${EndIf}
Thank you very much - I changed the code a little bit so that it compares the result with my defined PID and use an existing process in general instead of creating a new one. So far it works.
Now the PID and Windowtitle is necessary to know, but the Windowtitle should be created from PID automatically - is this possible?
Leave a comment:
-
-
PHP Code:!include LogicLib.nsh
!include WinMessages.nsh
ExecShell '' Notepad '' SW_SHOWMINIMIZED ; Instance we don't care about
!define /IfNDef STARTF_USESHOWWINDOW 0x0001
!define /IfNDef SW_SHOWMINNOACTIVE 7
System::Call '*(&l${NSIS_PTR_SIZE},p,p,p,i,i,i,i,i,i,i,i ${STARTF_USESHOWWINDOW},p ${SW_SHOWMINNOACTIVE},p,p,p,p)p.r1'
System::Call '*(p,p,i,i)p.r2'
System::Call 'KERNEL32::CreateProcess(p0,t "notepad.exe",p0,p0,i0,i0,p0,p0,pr1,pr2)i.r0'
${If} $0 <> 0
System::Call "*$2(p.r3,p.r4,i.r0,i)"
System::Call 'KERNEL32::CloseHandle(pr3)'
System::Call 'KERNEL32::CloseHandle(pr4)'
${EndIf}
System::Free $1
System::Free $2
ExecShell '' Notepad '' SW_SHOWMINIMIZED ; Instance we don't care about
Sleep 1234 ; Wait for Notepad to start
!define CLASS "Notepad"
StrCpy $2 ""
loop:
FindWindow $1 "${CLASS}" "" "" $2
StrCpy $2 $1
${If} $1 P<> 0
${AndIf} $0 <> 0 ; PID
System::Call 'USER32::GetWindowThreadProcessId(p$1,*i0r3)'
System::Call 'USER32::IsWindowVisible(p$1)i.r4'
${If} $3 = $0
${AndIf} $4 <> 0
System::Call 'USER32::SetForegroundWindow(p$1)'
System::Call 'USER32::SwitchToThisWindow(p$1,i1)'
${Else}
Goto loop
${EndIf}
${EndIf}
Leave a comment:
-
-
Got a few steps close to my aim, but fails if there are two instances of the Windows. The script should go through all one after the other...
Function .onGUIEnd
loop:
Pop $0
StrCpy $mypid "2424"
;FindWindow $0
;IsWindow $0 0 +2
;System::Call 'user32::SetForegroundWindow(i r0)'
FindWindow $0 "" "AquaKeyTest"
IsWindow $0 0 +2
System::Call 'USER32::GetWindowThreadProcessId(p$0,*i0r1)'
MessageBox MB_OK "mypid(Gesucht)=$mypid und PID(Gefunden)=$1"
${If} $1 = $mypid
MessageBox MB_OK "Test"
System::Call 'user32::SetForegroundWindow(i r0)'
IsWindow $0 done
${EndIf}
System::Call "$R0"
goto loop
Leave a comment:
-
-
thanks, the line is accepted now.
But I'm afraid I dont know how to search trough all windows in a loop until the process id matches the defined one (that was passed as argument to .exe). That's the final taget for my project.
The code I've now shows endless the same item and can't compare the id I gave as parameter (not even when hardcoded as variable) - it always says they match.
Can you help me a little bit with this task as I'm very new to NSIS and struggling with the help websites at all?
Leave a comment:
-
-
Unfortunately it doesn't work:
Error: unterminated string parsing line at C:\InnoSetup-Software\Source - NSIS\Focus.nsi:52
-> System::Call 'USER32::GetWindowThreadProcessId(p$0,*i0r1)
!include LogicLib.nsh
;!define mypid "3044"
Function .onGUIEnd
FindWindow $0 "" "Aqua'S KeyTest"
IsWindow $0 0 +2
System::Call 'USER32::GetWindowThreadProcessId(p$0,*i0r1)
${If} $1 == $mypid
System::Call 'user32::SetForegroundWindow(i r0)'
${EndIf}
FunctionEnd
Can you send me a little more specific code example I can work with?
Leave a comment:
-
Leave a comment: