Announcement

Collapse
No announcement yet.

SetForegroundWindow by PID

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dragodraki
    replied
    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.

    Leave a comment:


  • Dragodraki
    replied
    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:


  • Anders
    replied
    Seems to me you did not try very hard.
    PHP Code:
    !include LogicLib.nsh
    Function PSEnum
    ${If} $$MyPid
        DetailPrint 
    "Found $1"
        
    StrCpy $""
    ${EndIf}
    FunctionEnd
     
    Section
    GetFunctionAddress 
    $0 PSEnum
    PS
    ::Enum $0
    SectionEnd 

    Leave a comment:


  • Dragodraki
    replied
    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:


  • Anders
    replied
    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:


  • Dragodraki
    replied
    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:


  • Anders
    replied
    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 
    $""
    loop:
        
    FindWindow $"" "" "" $2
        StrCpy 
    $$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} $!= ""
            
    ${AndIf} $<> 0
                DetailPrint 
    "Visible window $1 has title $5"
            
    ${EndIf}
            Goto 
    loop
        
    ${EndIf} 
    SectionEnd 

    Leave a comment:


  • Dragodraki
    replied
    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:


  • Anders
    replied
    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:


  • Dragodraki
    replied
    !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:


  • Anders
    replied
    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,${STARTF_USESHOWWINDOW},${SW_SHOWMINNOACTIVE},p,p,p,p)p.r1'
    System::Call '
    *(p,p,i,i)p.r2'
    System::Call '
    KERNEL32::CreateProcess(p0,"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 $""
    loop:
    FindWindow $"${CLASS}" "" "" $2
    StrCpy 
    $$1
    ${If} $1 P<> 0
    ${AndIf} $<> PID
        System
    ::Call 'USER32::GetWindowThreadProcessId(p$1,*i0r3)'
        
    System::Call 'USER32::IsWindowVisible(p$1)i.r4'
        
    ${If} $= $0
        
    ${AndIf} $<> 0
            System
    ::Call 'USER32::SetForegroundWindow(p$1)'
            
    System::Call 'USER32::SwitchToThisWindow(p$1,i1)'
        
    ${Else}
            Goto 
    loop
        
    ${EndIf}
    ${EndIf} 

    Leave a comment:


  • Dragodraki
    replied
    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:


  • Dragodraki
    replied
    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:


  • Anders
    replied
    Just a typo, missing the final '. I edited my post.

    Leave a comment:


  • Dragodraki
    replied
    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:

Working...
X