Jump to content

Get PID of application opening a non-exe file through cmd?


 Share

Recommended Posts

Check out 

ProcessList

You can run it after your run command for the name of your application. Sort the list to get them in PID sequence, I'm guessing the last process will be the highest PID (not guaranteed).

Alternatively (and more robustly) if your process takes a file name as an argument, change your Run line to avoid the whole cmd shell creation and execute the media player with the file as a command line option directly, then you will get the correct PID returned.

I also just saw this:

Which looks like a lot of effort for what you want.... I see it is pretty old and I've not used it. G'luck.

Edited by SlackerAl
Found child process function

Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Link to comment
Share on other sites

47 minutes ago, SlackerAl said:

Sort the list to get them in PID sequence, I'm guessing the last process will be the highest PID (not guaranteed).

This is flat-out wrong. On Windows, the algorithm to generate PIDs is intentionally undocumented, it may change from OS version to version, and unlike on *nix, it is NOT sequential.

Link to comment
Share on other sites

ProcessList + _WinAPI_GetProcessCommandLine() might work, but the initially command did not launch a media player for me (though I thought it should), maybe Win10 related?

Can't you just use ShellExecute()?

Edited by KaFu
Link to comment
Share on other sites

13 minutes ago, KaFu said:

but the initially command did not launch a media player for me

Do not put your start file inside double quotes.  It is interpreted by start as a title...

Link to comment
Share on other sites

This works for me :

; If the file or folder has a space in it, you must surround it with quotes.
; https://www.computerhope.com/starthlp.htm

Local $iPID, $sPath, $sFile
$sPath = @ScriptDir & '\' 
$sFile = '"Music 01.mp3"' ; ==> 'Music 01.mp3' would fail !
ConsoleWrite("> >>> " & $sPath & $sFile & @CRLF)
$iPID  = Run(@ComSpec & ' /c Start ' & $sPath & $sFile, '', @SW_HIDE)
MsgBox(262144, "Return :", "PID : " & $iPID & @CRLF & "Error : " & @error & @CRLF)

 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

Ya it is because you $sPath is not embedded in double-quotes.  But it won't work if your @ScriptDir contains a white space...

And if you need to have double-quotes use this :

Local $iPID = Run(@ComSpec & ' /c start "dummy title" ' & '"David Bowie StarMan.wav"')

 

Edited by Nine
Link to comment
Share on other sites

1 hour ago, Nine said:

But it won't work if your @ScriptDir contains a white space... And if you need to have double-quotes use this :

Local $iPID = Run(@ComSpec & ' /c start "dummy title" ' & '"David Bowie StarMan.wav"')

 

Yes, the syntax is a little tricky :lol:.

START has a peculiarity involving double quotes around the first parameter. If the first parameter has double quotes it uses that as the optional TITLE for the new window.

You can also use /D :

Local $iPID, $sPath, $sFile

$sPath = '"' & @ScriptDir & '\Folder 01\"'
$sFile = '"Music 01.mp3"'
$iPID  = Run(@ComSpec & ' /c Start "" /D '  & $sPath & " " & $sFile, '', @SW_HIDE)
MsgBox(262144, "Return :", "PID : " & $iPID & @CRLF & "Error : " & @error & @CRLF)

 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

Ah, didn't know the special syntax, good to know :).

#include <Array.au3>
#include <WinAPIProc.au3>

$sFilename = '"' & @ScriptDir & '\123.mp3"'
$iPID = Run(@ComSpec & ' /c start "Titel" ' & $sFilename,"",@SW_HIDE)

Sleep(2000) ; wait for the default program to launch

$aList = ProcessList()
For $i = 1 To $aList[0][0]
    if StringInStr(_WinAPI_GetProcessCommandLine($aList[$i][1]),$sFilename) Then
        MsgBox(0,"","PID=" & $aList[$i][0] & @crlf & @crlf & "Name=" & $aList[$i][1] & @crlf & @crlf & _WinAPI_GetProcessCommandLine($aList[$i][1]))
    endif
Next

 

Link to comment
Share on other sites

Hi @KaFu !

I'm probably already tired and missing something ;).

3 hours ago, KaFu said:

MsgBox(0,"","PID=" & $aList[$i][0] & @crlf & @crlf & "Name=" & $aList[$i][1] & @crlf ....

PID=" & $aList[$i][0] ==> according to ProcessList the PID has the index [$i][[1].

Name=" & $aList[$i][1] ==> according to ProcessList the Name has the index [$i][[0].

The .mp3 file is executed by the application associated with the .mp3 extension (in my case vlc.exe).

3 hours ago, KaFu said:

if StringInStr(_WinAPI_GetProcessCommandLine($aList[$i][1]),$sFilename) Then

This StringInStr will never come TRUE, as far as i can say.

 

#include <Array.au3>
#include <WinAPIProc.au3>

$sFilename = '"' & @ScriptDir & '\Music 01.mp3"'
$iPID = Run(@ComSpec & ' /c start "Titel" ' & $sFilename,"",@SW_HIDE)

ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
ConsoleWrite("+ Filename     :  <" & $sFilename & ">" & @CRLF)
ConsoleWrite("+ PID Run(...) :  <" & $iPID & ">" & @CRLF)
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
Sleep(2000) ; wait for the default program to launch
$aList = ProcessList()
For $i = 1 To $aList[0][0]
    If $aList[$i][0] = "vlc.exe" Then
        ConsoleWrite(">  PID = <" & $aList[$i][1] & ">" & _
                     "   Name = <" & $aList[$i][0] & ">" & _
                     "   CommandLine = <" & _WinAPI_GetProcessCommandLine($aList[$i][1]) & ">" & @CRLF)
    EndIf
Next
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)

Would you be so kind to explain, what exactly you are trying to achieve? TIA 🙂

Edited by Musashi
typo

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

Yep, confused PID and Name of process just by guessing / assuming :), but still your code reports this to me:

>  PID = <7812>   Name = <vlc.exe>   CommandLine = <--started-from-file "C:\_Data\!_Keep\AMT-Workbench_MPV-Test\123.mp3">

Maybe you have to increase sleep time (and remove the "vlc.exe" check, works for me without it)?

 

Edit:

#include <Array.au3>
#include <WinAPIProc.au3>

$sFilename = '"' & @ScriptDir & '\123.mp3"'
$iPID = Run(@ComSpec & ' /c start "Titel" ' & $sFilename,"",@SW_HIDE)

ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
ConsoleWrite("+ Filename     :  <" & $sFilename & ">" & @CRLF)
ConsoleWrite("+ PID Run(...) :  <" & $iPID & ">" & @CRLF)
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
Sleep(2000) ; wait for the default program to launch
$aList = ProcessList()
For $i = 1 To $aList[0][0]
    if StringInStr(_WinAPI_GetProcessCommandLine($aList[$i][1]),$sFilename) then
        ConsoleWrite(">  PID = <" & $aList[$i][1] & ">" & _
                     "   Name = <" & $aList[$i][0] & ">" & _
                     "   CommandLine = <" & _WinAPI_GetProcessCommandLine($aList[$i][1]) & ">" & @CRLF)
    EndIf
Next
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)

Reports to me:

>  PID = <800>   Name = <vlc.exe>   CommandLine = <--started-from-file "C:\_Data\!_Keep\AMT-Workbench_MPV-Test\123.mp3">

Edited by KaFu
Link to comment
Share on other sites

2 hours ago, KaFu said:

Yep, confused PID and Name of process just by guessing / assuming :), but still your code reports this to me:

>  PID = <7812>   Name = <vlc.exe>   CommandLine = <--started-from-file "C:\_Data\!_Keep\AMT-Workbench_MPV-Test\123.mp3">

Maybe you have to increase sleep time (and remove the "vlc.exe" check, works for me without it)?

 

Edit:

#include <Array.au3>
#include <WinAPIProc.au3>

$sFilename = '"' & @ScriptDir & '\123.mp3"'
$iPID = Run(@ComSpec & ' /c start "Titel" ' & $sFilename,"",@SW_HIDE)

ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
ConsoleWrite("+ Filename     :  <" & $sFilename & ">" & @CRLF)
ConsoleWrite("+ PID Run(...) :  <" & $iPID & ">" & @CRLF)
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
Sleep(2000) ; wait for the default program to launch
$aList = ProcessList()
For $i = 1 To $aList[0][0]
    if StringInStr(_WinAPI_GetProcessCommandLine($aList[$i][1]),$sFilename) then
        ConsoleWrite(">  PID = <" & $aList[$i][1] & ">" & _
                     "   Name = <" & $aList[$i][0] & ">" & _
                     "   CommandLine = <" & _WinAPI_GetProcessCommandLine($aList[$i][1]) & ">" & @CRLF)
    EndIf
Next
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)

Reports to me:

>  PID = <800>   Name = <vlc.exe>   CommandLine = <--started-from-file "C:\_Data\!_Keep\AMT-Workbench_MPV-Test\123.mp3">

Doesn't work for me, it reports
+ Filename     :  <"C:\Users\DEV\Desktop\123.mp3">
+ PID Run(...) :  <10608>
which I assume is still the CMD that launched since taskkill /PID 10608 outputs , `The process "11984" is not found.`

 

13 hours ago, SlackerAl said:

Check out 

ProcessList

You can run it after your run command for the name of your application. Sort the list to get them in PID sequence, I'm guessing the last process will be the highest PID (not guaranteed).

Alternatively (and more robustly) if your process takes a file name as an argument, change your Run line to avoid the whole cmd shell creation and execute the media player with the file as a command line option directly, then you will get the correct PID returned.

I also just saw this:

Which looks like a lot of effort for what you want.... I see it is pretty old and I've not used it. G'luck.

I have tried that UDF but it just opens up a bunch of Excel-ish spreadsheet with a bunch of processes in it when using _ChildProcess($PID)

Link to comment
Share on other sites

Sorry I meant process 10608 is not found, im blind

Just now, maoyuusha said:

Doesn't work for me, it reports
+ Filename     :  <"C:\Users\DEV\Desktop\123.mp3">
+ PID Run(...) :  <10608>
which I assume is still the CMD that launched since taskkill /PID 10608 outputs , `The process "11984" is not found.`

 

I have tried that UDF but it just opens up a bunch of Excel-ish spreadsheet with a bunch of processes in it when using _ChildProcess($PID)

 

Link to comment
Share on other sites

2 hours ago, KaFu said:

[...] but still your code reports this to me:

>  PID = <7812>   Name = <vlc.exe>   CommandLine = <--started-from-file "C:\_Data\!_Keep\AMT-Workbench_MPV-Test\123.mp3">

Maybe you have to increase sleep time (and remove the "vlc.exe" check, works for me without it)?

I executed your script, but the CommandLine is still empty - Sleep(5000).

I narrowed the script down to the plain process list. The file 123.mp3 was previously started with VLC (the VLC window is open and the music is running). That means "Run(@ComSpec & ' /c start ..." doesn't matter anymore.

#include <Array.au3>
#include <WinAPIProc.au3>

Local $aList = ProcessList()
For $i = 1 To $aList[0][0]
    ConsoleWrite("!  PID = <" & $aList[$i][1] & ">" & _
                 "   Name = <" & $aList[$i][0] & ">" & _
                 "   CommandLine = <" & _WinAPI_GetProcessCommandLine($aList[$i][1]) & ">" & @CRLF)
Next

This is the output (abbreviated) :

Spoiler

==> [...]

!  PID = <3412>   Name = <firefox.exe>   CommandLine = <>
!  PID = <936>   Name = <SciTE.exe>   CommandLine = <"C:\AutoIt\Projekte\Testprogramme\Test-KaFu-Start01.au3">
!  PID = <4796>   Name = <vlc.exe>   CommandLine = <>
!  PID = <128>   Name = <Autoit3wrapper.exe>   CommandLine = </run /prod /ErrorStdOut /in "C:\AutoIt\Projekte\Testprogramme\Test-MU-Start02.au3" /UserParams>
!  PID = <2744>   Name = <AutoIt3.exe>   CommandLine = </ErrorStdOut "C:\AutoIt\Projekte\Testprogramme\Test-MU-Start02.au3">

I found the problem, my goodness, I'm stupid :doh:. #AutoIt3Wrapper_UseX64 = Y has solved the problem.

+ Filename     :  <"C:\AutoIt\Projekte\Testprogramme\123.mp3">
+ PID Run(...) :  <1224>
+  PID = <2516>   Name = <vlc.exe>   CommandLine = <--started-from-file "C:\AutoIt\Projekte\Testprogramme\123.mp3">

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

12 hours ago, KaFu said:

ProcessList + _WinAPI_GetProcessCommandLine() might work, but the initially command did not launch a media player for me (though I thought it should), maybe Win10 related?

Can't you just use ShellExecute()?

I can't use ShellExecute() since in this particular use case, I still need the PID of the cmd to close it in case the user inputs a non-existing file to close the error window automatically. ShellExecute is unable to do that and the script just pauses until the user closes the error window. Unless theres an option to get the PID of both cmd and the opened process that I am unaware of.

Link to comment
Share on other sites

11 minutes ago, maoyuusha said:

I can't use ShellExecute() since in this particular use case, I still need the PID of the cmd to close it in case the user inputs a non-existing file to close the error window automatically. ShellExecute is unable to do that and the script just pauses until the user closes the error window. Unless theres an option to get the PID of both cmd and the opened process that I am unaware of.

Assuming the program is installed in @ProgramFilesDir\... you can also call the .mp3 like this :

#AutoIt3Wrapper_UseX64 = Y ; <== 32-Bit = N
#include <Array.au3>
#include <WinAPIProc.au3>

Local $sFilename = '"' & @ScriptDir & '\123.mp3"'
Local $iPID = Run(@ProgramFilesDir & '\VideoLAN\VLC\VLC.exe ' & $sFilename , "",@SW_HIDE)

ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
ConsoleWrite("+ Filename     :  <" & $sFilename & ">" & @CRLF)
ConsoleWrite("+ PID Run(...) :  <" & $iPID & ">" & @CRLF)
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
Sleep(2000) ; wait for the default program to launch

Local $aList = ProcessList()
For $i = 1 To $aList[0][0]
    If StringInStr(_WinAPI_GetProcessCommandLine($aList[$i][1]),$sFilename) then
        ConsoleWrite("+  PID = <" & $aList[$i][1] & ">" & _
                     "   Name = <" & $aList[$i][0] & ">" & _
                     "   CommandLine = <" & _WinAPI_GetProcessCommandLine($aList[$i][1]) & ">" & @CRLF)
    EndIf
Next
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)

Output :

< ------------------------------------------------------------------------------
+ Filename     :  <"C:\AutoIt\Projekte\Testprogramme\123.mp3">
+ PID Run(...) :  <4184>
< ------------------------------------------------------------------------------
+  PID = <4184>   Name = <vlc.exe>   CommandLine = <"C:\AutoIt\Projekte\Testprogramme\123.mp3">
< ------------------------------------------------------------------------------

@maoyuusha ; The problem with terminating VLC in case of an error still has to be solved. But I am too tired for that now 😴.

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

8 minutes ago, Musashi said:

Assuming the program is installed in @ProgramFilesDir\... you can also call the .mp3 like this :

#AutoIt3Wrapper_UseX64 = Y ; <== 32-Bit = N
#include <Array.au3>
#include <WinAPIProc.au3>

Local $sFilename = '"' & @ScriptDir & '\123.mp3"'
Local $iPID = Run(@ProgramFilesDir & '\VideoLAN\VLC\VLC.exe ' & $sFilename , "",@SW_HIDE)

ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
ConsoleWrite("+ Filename     :  <" & $sFilename & ">" & @CRLF)
ConsoleWrite("+ PID Run(...) :  <" & $iPID & ">" & @CRLF)
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)
Sleep(2000) ; wait for the default program to launch

Local $aList = ProcessList()
For $i = 1 To $aList[0][0]
    If StringInStr(_WinAPI_GetProcessCommandLine($aList[$i][1]),$sFilename) then
        ConsoleWrite("+  PID = <" & $aList[$i][1] & ">" & _
                     "   Name = <" & $aList[$i][0] & ">" & _
                     "   CommandLine = <" & _WinAPI_GetProcessCommandLine($aList[$i][1]) & ">" & @CRLF)
    EndIf
Next
ConsoleWrite("< ------------------------------------------------------------------------------" & @CRLF)

Output :

< ------------------------------------------------------------------------------
+ Filename     :  <"C:\AutoIt\Projekte\Testprogramme\123.mp3">
+ PID Run(...) :  <4184>
< ------------------------------------------------------------------------------
+  PID = <4184>   Name = <vlc.exe>   CommandLine = <"C:\AutoIt\Projekte\Testprogramme\123.mp3">
< ------------------------------------------------------------------------------

@maoyuusha ; The problem with terminating VLC in case of an error still has to be solved. But I am too tired for that now 😴.

I cant pre-determine which music player its gonna open.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...