Args() - Returns command line parameters as array

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Args() - Returns command line parameters as array

23 Aug 2014, 18:15

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]
My Scripts and Functions: V1  V2
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Args() - Returns command line parameters as array

26 Aug 2014, 08:41

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?
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Args() - Returns command line parameters as array

26 Aug 2014, 09:07

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.
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Args() - Returns command line parameters as array

26 Aug 2014, 11:48

MsgBox wrote:---------------------------
Empty CmdLine
---------------------------
Count = 2
1=C:\Program
2=Files\AutoHotkey\AutoHotkey.exe
3=
4=
5=
---------------------------
OK
---------------------------
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Args() - Returns command line parameters as array

26 Aug 2014, 12:03

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 :)
arcticir
Posts: 694
Joined: 17 Nov 2013, 11:32

Re: Args() - Returns command line parameters as array

28 Aug 2014, 18:13

I have a question, how to use DllCall ("GetCommandLine", "Str"), Get other processes on the command line?
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Args() - Returns command line parameters as array

28 Aug 2014, 18:57

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.
arcticir
Posts: 694
Joined: 17 Nov 2013, 11:32

Re: Args() - Returns command line parameters as array

29 Aug 2014, 07:47

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):""
	}
Dougal
Posts: 26
Joined: 19 Aug 2014, 16:51

Re: Args() - Returns command line parameters as array

30 Aug 2014, 03:25

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
Dougal
Posts: 26
Joined: 19 Aug 2014, 16:51

Re: Args() - Returns command line parameters as array

30 Aug 2014, 05:12

Do you have a fix for the spaces in program name?

It also isn't returning parameters set in SciTE4AHK.
User avatar
joedf
Posts: 8951
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: Args() - Returns command line parameters as array

30 Aug 2014, 06:31

There might be an issue with SciTE4AHK...
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
Dougal
Posts: 26
Joined: 19 Aug 2014, 16:51

Re: Args() - Returns command line parameters as array

30 Aug 2014, 08:35

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.
Dougal
Posts: 26
Joined: 19 Aug 2014, 16:51

Re: Args() - Returns command line parameters as array

30 Aug 2014, 20:06

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
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Args() - Returns command line parameters as array

30 Aug 2014, 20:26

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
Dougal
Posts: 26
Joined: 19 Aug 2014, 16:51

Re: Args() - Returns command line parameters as array

13 Oct 2014, 03:08

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.
Dougal
Posts: 26
Joined: 19 Aug 2014, 16:51

Re: Args() - Returns command line parameters as array

17 Jan 2015, 02:55

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
Guest

Re: Args() - Returns command line parameters as array

17 Mar 2015, 03:03

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

Code: Select all

/q /item:c:\some folder
Is there a way to get the exact arguments that were passed to my script including quotes?
User avatar
joedf
Posts: 8951
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: Args() - Returns command line parameters as array

17 Mar 2015, 11:27

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^""
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: KruschenZ and 53 guests