Page 1 of 2
Args() - Returns command line parameters as array
Posted: 23 Aug 2014, 18:15
by SKAN
Args( CmdLine, Skip )
- CmdLine: To parse scripts own parameters, pass DllCall( "GetCommandLine", "Str" )
CmdLine can be anything, even imaginary parameters for mere test purposes.
- Skip: The no. of parameters to skip ( from left ).
For compiled scripts, the first parameter will be the executable which can be skipped by passing 1
For uncompiled, it can be 2, that is A_AhkPath and A_ScriptFullpath will be skipped
Additionally, a 'reloaded script' would have /restart in its parameters.
argv[0] will contain the number of parameters retrieved. It will be a negative number if Skip > available
Code: Select all
Args( CmdLine := "", Skip := 0 ) { ; By SKAN, http://goo.gl/JfMNpN, CD:23/Aug/2014 | MD:24/Aug/2014
Local pArgs := 0, nArgs := 0, A := []
pArgs := DllCall( "Shell32\CommandLineToArgvW", "WStr",CmdLine, "PtrP",nArgs, "Ptr" )
Loop % ( nArgs )
If ( A_Index > Skip )
A[ A_Index - Skip ] := StrGet( NumGet( ( A_Index - 1 ) * A_PtrSize + pArgs ), "UTF-16" )
Return A, A[0] := nArgs - Skip, DllCall( "LocalFree", "Ptr",pArgs )
}
Usage example:
CmdLine := DllCall( "GetCommandLine", "Str" )
argv := Args( CmdLine )
; or simply
argv := Args( DllCall( "GetCommandLine", "Str" ) )
Test script:
Code: Select all
#Warn
#SingleInstance, Force
CmdLine := DllCall( "GetCommandLine", "Str" )
Skip := ( A_IsCompiled ? 1 : 2 )
argv := Args( CmdLine, Skip )
Msgbox % "Count = " argv[0] "`n1=" argv[1] "`n2=" argv[2] "`n3=" argv[3] "`n4=" argv[4] "`n5=" argv[5]
Re: Args() - Returns command line parameters as array
Posted: 26 Aug 2014, 08:41
by just me
I'm wondering about Args( CmdLine := "", Skip := 0 ). What will the funtion do if CmdLine is empty? Wouldn't it be better to call GetCommandLine() internally in this case?
Re: Args() - Returns command line parameters as array
Posted: 26 Aug 2014, 09:07
by SKAN
just me wrote:What will the funtion do if CmdLine is empty?
argv[0] will be 1
argv[1] will be fullpath of Autohotkey executable ( compiled or not )
just me wrote:Wouldn't it be better to call GetCommandLine() internally in this case?
Initially I put a ternary and then removed it. For a reloaded script, StringReplace is required to remove
/restart from command line.
Re: Args() - Returns command line parameters as array
Posted: 26 Aug 2014, 11:48
by just me
MsgBox wrote:---------------------------
Empty CmdLine
---------------------------
Count = 2
1=C:\Program
2=Files\AutoHotkey\AutoHotkey.exe
3=
4=
5=
---------------------------
OK
---------------------------
Re: Args() - Returns command line parameters as array
Posted: 26 Aug 2014, 12:03
by SKAN
Whereas, my MsgBox wrote:---------------------------
test.ahk
---------------------------
Count = 1
1=D:\AutoHotkey\AutoHotkeyU64.exe
2=
3=
4=
5=
---------------------------
OK
---------------------------
No space in my A_AhkPath and hence it escaped me
![Smile :)](./images/smilies/icon_e_smile.gif)
Re: Args() - Returns command line parameters as array
Posted: 26 Aug 2014, 19:31
by joedf
![Facepalm :facepalm:](./images/smilies/facepalm.png)
SKAN ->
![Hehehe :HeHe:](./images/smilies/smiley_trollface.png)
Re: Args() - Returns command line parameters as array
Posted: 28 Aug 2014, 18:13
by arcticir
I have a question, how to use DllCall ("GetCommandLine", "Str"), Get other processes on the command line?
Re: Args() - Returns command line parameters as array
Posted: 28 Aug 2014, 18:57
by SKAN
arcticir wrote:how to use DllCall ("GetCommandLine", "Str"), Get other processes on the command line?
Short answer: Create a thread in the target process and execute GetCommandLine() from that thread.
Here is a version from
Sean:
http://goo.gl/o8L3Q7
Let me know if you need help.
Re: Args() - Returns command line parameters as array
Posted: 29 Aug 2014, 07:47
by arcticir
Thanks.
but I can not find direct access to the command-line approach.
I have been using WMI to obtain,
it's just slower.
Code: Select all
CommandLine:=winmgmt("CommandLine","Where ProcessId = " PID "")
winmgmt(v,w:="",d:="Win32_Process",m:="winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2"){
s:=[]
for i in ComObjGet(m).ExecQuery("Select " (v?v:"*") " from " d (w ? " " w :""))
s.Insert(i[v])
return s.MaxIndex()?(s.MaxIndex()=1?s.1:s):""
}
Re: Args() - Returns command line parameters as array
Posted: 30 Aug 2014, 03:25
by Dougal
Thank you. I have wanted to process the command line parameters in a function, but couldn't work out how to (%0 etc return the function parameters not the script parameters). This will allow me to do what I was looking for.
Cheers
Re: Args() - Returns command line parameters as array
Posted: 30 Aug 2014, 05:12
by Dougal
Do you have a fix for the spaces in program name?
It also isn't returning parameters set in SciTE4AHK.
Re: Args() - Returns command line parameters as array
Posted: 30 Aug 2014, 06:31
by joedf
There might be an issue with SciTE4AHK...
Re: Args() - Returns command line parameters as array
Posted: 30 Aug 2014, 08:35
by Dougal
joedf wrote:There might be an issue with SciTE4AHK...
Possible. I also find that the parameters set in SciTE4AHK do not get passed to the script when using debugger. I didn't bother trying to run my test script for Args in debug mode for that reason.
Re: Args() - Returns command line parameters as array
Posted: 30 Aug 2014, 11:22
by joedf
Ahh Ok, I see..
Re: Args() - Returns command line parameters as array
Posted: 30 Aug 2014, 20:06
by Dougal
When I set "MyParameter" as parameter in SciTE4AHK, %1% returns it, but Args() does not - args[0] is always 2, and Args[1] and Args[2] are
C:\Program and
Files\AutoHotkey\AutoHotkey.exe respectively.
Looking at the script process via Process Explorer, the command line SciTE4AHK runs is
Code: Select all
"C:\Program Files\AutoHotkey\AutoHotkey.exe" /ErrorStdOut "D:\Dougal\Documents\AutoHotkey\Lib\args.ahk" MyParameter
so the parameter is being included in the autohotkey call, but DllCall( "Shell32\CommandLineToArgvW", "WStr",CmdLine, "PtrP",nArgs, "Ptr" ) isn't returning it for some reason.
Compiling the script and running with parameters also fails to return them. Scipt I am using to test:
Code: Select all
iPid := DllCall("GetCurrentProcessId")
MsgBox % iPID ; to check command line in Process Explorer, paraemetrs are present
msgbox %1% ; this returns "MyParameter"
msgbox % args()[args()[0]] ; this returns last part of AHK exe eg "Files\AutoHotkey\AutoHotkey.exe"
ExitApp
Args( CmdLine := "", Skip := 0 ) { ; By SKAN, http://goo.gl/JfMNpN, CD:23/Aug/2014 | MD:24/Aug/2014
Local pArgs := 0, nArgs := 0, A := []
pArgs := DllCall( "Shell32\CommandLineToArgvW", "WStr",CmdLine, "PtrP",nArgs, "Ptr" )
Loop % ( nArgs )
If ( A_Index > Skip )
A[ A_Index - Skip ] := StrGet( NumGet( ( A_Index - 1 ) * A_PtrSize + pArgs ), "UTF-16" )
Return A, A[0] := nArgs - Skip, DllCall( "LocalFree", "Ptr",pArgs )
}
I am using SciTE4AHK 3.0.06, with AHK 1.1.15.04 on Win7x64.
Cheers
Re: Args() - Returns command line parameters as array
Posted: 30 Aug 2014, 20:26
by SKAN
You need to insert
CmdLine := DllCall( "GetCommandLine", "Str" ) just above your following lines and pass CmdLine as parameter to Args().
Dougal wrote:Code: Select all
msgbox % args()[args()[0]] ; this returns last part of AHK exe eg "Files\AutoHotkey\AutoHotkey.exe"
ExitApp
Re: Args() - Returns command line parameters as array
Posted: 13 Oct 2014, 03:08
by Dougal
SKAN wrote:You need to insert CmdLine := DllCall( "GetCommandLine", "Str" ) just above your following lines and pass CmdLine as parameter to Args().
That fixed it, working beautifully now. Thanks for the help.
Re: Args() - Returns command line parameters as array
Posted: 17 Jan 2015, 02:55
by Dougal
To make it self contained, I now use this function in my library:
Code: Select all
aGetArgs(bAll := false) {
/*
Based on code By SKAN, http://goo.gl/JfMNpN, CD:23/Aug/2014 | MD:24/Aug/2014
Modified by Dougal 17Jan15
Returns array of strings, element 0 contains array count
Includes commandline parts if bAll = true
Otherwise strips non-parameter parts depending on how it was called:
Compiled script
removes compiled script name
Script
removes AutoHotkey executable and script name
SciTe4AutoHotkey
removes AutoHotkey executable, /ErrorStdOut parameter (if present) and script name
*/
sCmdLine := DllCall( "GetCommandLine", "Str" )
pArgs := 0, nArgs := 0, aArgs := []
pArgs := DllCall( "Shell32\CommandLineToArgvW", "WStr",sCmdLine, "PtrP",nArgs, "Ptr" )
; get command line parts from memory
Loop % (nArgs)
aArgs.insert(StrGet(NumGet((A_Index - 1 ) * A_PtrSize + pArgs ), "UTF-16"))
if not bAll { ; remove calling program parts
; remove AutoHotkey.exe if not compiled script
if not A_IsCompiled {
aArgs.remove(1)
nArgs -= 1
}
; remove /ErrorStdOut (run within SciTE4AutoHotkey)
if (aArgs[1] = "/ErrorStdOut") {
aArgs.remove(1)
nArgs -= 1
}
; remove (compiled) script name
aArgs.remove(1)
nArgs -= 1
}
aArgs[0] := nArgs
DllCall("LocalFree", "Ptr", pArgs)
return, aArgs
}
It works with scripts launched by installed AutoHotkey, compiled scripts, and scripts run from within SciTe4. Having DllCall( "GetCommandLine", "Str" ) inside the function also works with scripts restarted as admin (used the above code to get the parameters to pass to the restarted script).
Cheers
Re: Args() - Returns command line parameters as array
Posted: 17 Mar 2015, 03:03
by Guest
I'm having an issue using this function, I need to pass whatever arguments my script receives to another application, the problem is that
quotes are stripped.
example:
Code: Select all
<myscript.exe> /q /item:"c:\some folder"
will result in
Is there a way to get the exact arguments that were passed to my script including quotes?
Re: Args() - Returns command line parameters as array
Posted: 17 Mar 2015, 11:27
by joedf
You have to escape your quotes when passing it to your program. Ie.
^" so for you it should be :
Code: Select all
<myscript.exe> /q /item:"^"c:\some folder^""