Mat Posted December 20, 2010 Posted December 20, 2010 For ages I've been reusing the same old code to parse command line parameters. So I figured I'd change it slightly and make it into a UDF. The result is pretty good IMHO. To make it look nice, the main function is called 'CmdLine'. Usage is almost $_GET: CmdLine("arg") returns the value of "arg" What it does is put all the command line arguments in a global array ($CmdLine_Cache) in the form: [*][0] => Argument name, [*][1] => Value. The array is populated on either the first call to CmdLine or explicitly calling _CmdLine_Parse. The latter has several advantages that I will discuss later. CmdLine() is the 'unnamed' parameter. This is the one without an argument, so "program 'file.ext'" would set this to 'file.ext'. It can be set in the command line by using just the prefix (e.g. "program -- 'test'" will set it to 'test')Using _CmdLine_Parse has several added parameters that let you set the prefix and even say what arguments can be used. By default '--' is used (as per the GNU standard), but this is simple to change to '-' or '/' or anything else. The second argument is a zero based array of allowed arguments OR a '|' split list. This should not include prefixes! If a parameter is found that does not appear in the list then the error function specified in the third parameter is called. This should take a single argument which is given an error message from the function.Examples:--foo="This is the value of FOO"Foo = "This is the value of FOO"--foo "This is also the value of FOO"Foo = "This is also the value of FOO"--fooFoo = True--Test=123Foo = False$foo = CmdLine("foo") If Not $foo Then MsgBox(0, "Hmm...", "Foo was not defined") Else MsgBox(0, "Foo Found", "Foo = " & $foo) EndIf--Error 123Command line Error: Unrecognized parameter: ErrorFoo was not definedTest was not defined--foo="This is FOO" --test="This is TEST"Foo = This is FOOtest = This is TEST_CmdLine_Parse("-", "foo|test", "_CmdLine_Error") $foo = CmdLine("foo") If Not $foo Then MsgBox(0, "Hmm...", "Foo was not defined") Else MsgBox(0, "Foo Found", "Foo = " & $foo) EndIf $test = CmdLine("test") If Not $test Then MsgBox(0, "Hmm...", "Test was not defined") Else MsgBox(0, "Test Found", "Test = " & $test) EndIf Func _CmdLine_Error($sError) MsgBox(16, "Error", "Command line Error: " & $sError) EndFuncThere is more info in the function headers.CmdLine.au3:expandcollapse popupGlobal $CmdLine_Cache[1][2] = [[0, False]] ; #FUNCTION# ==================================================================================================================== ; Name ..........: CmdLine ; Description ...: Returns the value of the command line parameter. ; Syntax ........: CmdLine( [ $sParam ] ) ; Parameters ....: $sParam - [optional] A string specifying the command line parameter to retrieve. Default is a blank ; string, which is the parameter that does not have a named flag first. ; Return values .: Success - If the parameter has a value, then that is returned. If not then True is. ; Failure - False. Usually means that the parameter wasn't in the command line. ; Author(s) .....: Matt Diesel (Mat) ; Modified ......: ; Remarks .......: ; Related .......: _CmdLine_Parse ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func CmdLine($sParam = "") If $CmdLine_Cache[0][0] = 0 And $CmdLine[0] > 0 Then _CmdLine_Parse() If $sParam = "" Then Return $CmdLine_Cache[0][1] Else For $i = 1 To UBound($CmdLine_Cache) - 1 If $CmdLine_Cache[$i][0] = $sParam Then Return $CmdLine_Cache[$i][1] Next Return False EndIf EndFunc ;==>CmdLine ; #FUNCTION# ==================================================================================================================== ; Name ..........: _CmdLine_Parse ; Description ...: ; Syntax ........: _CmdLine_Parse( [ $sPrefix [, $asAllowed [, $sOnErrFunc ]]] ) ; Parameters ....: $sPrefix - [optional] The prefix for command line arguments. Default is '--'. It is recommended that ; it is one of the following standards (although it could be anything): ; |GNU - uses '--' to start arguments. <a href="http://www.gnu.org/prep/standards/ ; html_node/Command_002dLine-Interfaces.html">Page</a>. '--' on it's own sets the ; unnamed argument but always uses the next parameter, even if prefixed by '--'. ; E.g. '-- --file' will mean CmdLine() = '--file'. ; |MS - uses '-'. Arguments with values are seperated by a colon: ':'. <a ; href="http://technet.microsoft.com/en-us/library/ee156811.aspx">Page</a> ; |Slashes - Not sure where it's a standard, but using either backslash ( '\' ) or slash ; ( '/' ) is fairly common. AutoIt uses it :) Just make sure the user knows which ; one it is. ; $asAllowed - [optional] A zero based array of possible command line arguments that can be used. When an ; argument is found that does not match any of the values in the array, $sOnErrFunc is called ; with the first parameter being "Unrecognized parameter: PARAM_NAME". ; $sOnErrFunc - [optional] The function to call if an error occurs. ; Return values .: None ; Author(s) .....: Matt Diesel (Mat) ; Modified ......: ; Remarks .......: ; Related .......: This function must be called (rather than used in #OnAutoItStartRegister), as it uses a global array. ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _CmdLine_Parse($sPrefix = "--", $asAllowed = 0, $sOnErrFunc = "") If IsString($asAllowed) Then $asAllowed = StringSplit($asAllowed, "|", 3) For $i = 1 To $CmdLine[0] If $CmdLine[$i] = "--" Then If $i <> $CmdLine[0] Then $CmdLine_Cache[0][1] = $CmdLine[$i + 1] $i += 1 Else $CmdLine_Cache[0][1] = True EndIf ElseIf StringLeft($CmdLine[$i], StringLen($sPrefix)) = $sPrefix Then $CmdLine_Cache[0][0] = UBound($CmdLine_Cache) ReDim $CmdLine_Cache[$CmdLine_Cache[0][0] + 1][2] If StringInStr($CmdLine[$i], "=") Then $CmdLine_Cache[$CmdLine_Cache[0][0]][0] = StringLeft($CmdLine[$i], StringInStr($CmdLine[$i], "=", 2) - 1) $CmdLine_Cache[$CmdLine_Cache[0][0]][0] = StringTrimLeft($CmdLine_Cache[$CmdLine_Cache[0][0]][0], StringLen($sPrefix)) $CmdLine_Cache[$CmdLine_Cache[0][0]][1] = StringTrimLeft($CmdLine[$i], StringInStr($CmdLine[$i], "=", 2)) ElseIf StringInStr($CmdLine[$i], ":") Then $CmdLine_Cache[$CmdLine_Cache[0][0]][0] = StringLeft($CmdLine[$i], StringInStr($CmdLine[$i], ":", 2) - 1) $CmdLine_Cache[$CmdLine_Cache[0][0]][0] = StringTrimLeft($CmdLine_Cache[$CmdLine_Cache[0][0]][0], StringLen($sPrefix)) $CmdLine_Cache[$CmdLine_Cache[0][0]][1] = StringTrimLeft($CmdLine[$i], StringInStr($CmdLine[$i], ":", 2)) Else $CmdLine_Cache[$CmdLine_Cache[0][0]][0] = StringTrimLeft($CmdLine[$i], StringLen($sPrefix)) If ($i <> $CmdLine[0]) And (StringLeft($CmdLine[$i + 1], StringLen($sPrefix)) <> $sPrefix) Then $CmdLine_Cache[$CmdLine_Cache[0][0]][1] = $CmdLine[$i + 1] $i += 1 Else $CmdLine_Cache[$CmdLine_Cache[0][0]][1] = True EndIf EndIf If $asAllowed <> 0 Then For $n = 0 To UBound($asAllowed) - 1 If $CmdLine_Cache[$CmdLine_Cache[0][0]][0] = $asAllowed[$n] Then ContinueLoop 2 Next If $sOnErrFunc <> "" Then Call($sOnErrFunc, "Unrecognized parameter: " & $CmdLine_Cache[$CmdLine_Cache[0][0]][0]) EndIf Else If Not $CmdLine_Cache[0][1] Then $CmdLine_Cache[0][1] = $CmdLine[$i] Else If $sOnErrFunc <> "" Then Call($sOnErrFunc, "Unrecognized parameter: " & $CmdLine[$i]) EndIf EndIf Next EndFunc ;==>_CmdLine_ParseMat AutoIt Project Listing
AlienStar Posted January 5, 2011 Posted January 5, 2011 Mat .. I'm so sorry I didn't know ho to use this code coz I'm still as a newbie I didn't know how to import the application (or the place to set its location) to view the command line parameters thanks
Mat Posted January 5, 2011 Author Posted January 5, 2011 No probs If you want a simple one-line solution to the problem then you could just use: If StringInStr($CmdLineRaw, " /install") Then ; Install EndIf or alternatively, there is a very nice (and unfortunately not advertised) collection of basic snippets in SciTE under abbreviations. Go to: Edit > Insert Abbreviation and type "cmdlineswitch" to get a template statement that you can then edit with your parameters. If you'd rather use mine after those tow suggestions then read on: The easiest way to use my code is to save it as a file called "CmdLine.au3", and put it in the same directory as your script. You can then use this in your program: ; Leave these two lines at the top!! #include "CmdLine.au3" _CmdLine_Parse("/") ; Check command line parameters: If CmdLine("install") Then MsgBox(0, "Test", "The installation would be running right now.") ElseIf CmdLine("uninstall") Then MsgBox(0, "Test", "The UN-installation would be running right now.") Else MsgBox(0, "Test", "Not much going on...") EndIf For information on include the helpfile has it all (as usual). Although it may sound counter-intuitive, learn the language, THEN write your programs. If you try and write a program while the gradient is still steep on the learning curve then you'll only end up re-writing it later. Here's a sort of template based on the above: MyScript.zip Mat AutoIt Project Listing
AlienStar Posted January 5, 2011 Posted January 5, 2011 I have to clarify my request I put an example about adobe flash player , but I need solution for any application may has switches also I didn't understand where to insert the location of the app that I wanna use thanks for the help and sorry for inconvenience
Mat Posted January 5, 2011 Author Posted January 5, 2011 As said before, you must learn the language before trying to program... Me helping you know won't help you as much as you teaching yourself. Furthermore this thread is for an example, and as much as I am willing to help you, filling up pages of stuff that's only going to useful to you is what we have a pm system for. So here's what I'll do: Play around with the snippet I gave you, try to read it as though it was English (best way to deal with IF tests), and pm me tomorrow with what you know, and still need to know. Deal? Try it, you'll learn lot's AutoIt Project Listing
DigitalFacade82 Posted July 2, 2013 Posted July 2, 2013 (edited) Sorry to revive an old thread attack of the necro bump is back! But....possibly valid? I am attempting to use this to pass command line arguments to a wrapper script that I use to launch Notepad++. At the moment it is sh!tting me to tears that Notepad++ always launches in the same instance. I use Alt+Tab a LOT! So it is handy to Alt Tab between sessions...nope Notepad is always on the same tab and you have to pass it command line options of notepad++.exe -multiInst -nosession in order for it to launch as 1) In a new session 2) As full screen That brings me to my next problem. If I click my compiled exe script to launch Notepad++ it always launches as a new session. But I use right click a hell of a lot too! Currently Notepad++ everytime I reboot my computer seems to reset its self when it right click a file and launch from the standard Edit with Notepad++ that sometimes when it launches it isn't exactly minimised it launches maximised however the expand Window button defaults to resize the Window and make it about the size of the 3 buttons...actually screw it a screen shot is in order here to prove my point! (click to see full size version and check out the top left corner) So I figured that your script could be used to pass command arguments to my wrapper script from the right click context menu so that when I launch from right click and wondering where the f my window is I can pass it to my wrapper which should always allow it to be seen in full screen maximized instead of that cr@p you see in my screenshot. Right click context menu accepts a command line of %1 For some reason this does not work when I load it in to my wrapper script? Nothing happens? It seems to ignore %1 as command line argument, actually nothing happens at all? It doesn't even launch the application? Here is my script: $Title = "NotepadNewInst" #include <File.au3> #NoTrayIcon Func NotepadNewInst() Local $path=(@ScriptDir &'\') Run('notepad++.exe -multiInst -nosession ', $path, @SW_MAXIMIZE) Exit EndFunc ;==>NotepadNewInst() NotepadNewInst() Here it is modified: Note: My CmdLine.au3 is in C:Program Files (x86)AutoIt3Include $Title = "NotepadNewInst" #include <File.au3> #include <CmdLine.au3> _CmdLine_Parse("%1") Func NotepadNewInst() Local $path=(@ScriptDir &'\') If CmdLine("%1") Then Run('notepad++.exe -multiInst -nosession ' & '%1', $path, @SW_MAXIMIZE); Have tried all sorts of combinations of this none work? ;Run('notepad++.exe -multiInst -nosession ' & '%1', $path, @SW_MAXIMIZE) ;Run('notepad++.exe ' & '%1 ' &'-multiInst -nosession', $path, @SW_MAXIMIZE) ;Run('notepad++.exe %1 -multiInst -nosession', $path, @SW_MAXIMIZE) ;Run('notepad++.exe -multiInst -nosession %1', $path, @SW_MAXIMIZE) ;Run('notepad++.exe ' '%1', $path, @SW_MAXIMIZE) ;Run('notepad++.exe %1', $path, @SW_MAXIMIZE) EndIf Exit EndFunc ;==>NotepadNewInst() NotepadNewInst() Any thoughts on why it won't pass the command line argument of %1? Edited July 6, 2013 by DigitalFacade82
step887 Posted July 2, 2013 Posted July 2, 2013 So the issue is when you are right clicking, it going to notepad++ directly so it is not executing your program at all. So you will need to modify the context menu to point to your program. so I made a some changes to your program. Compile it and place the exe wherever you want it. Then open command prompt with admin rights browse to where the exe location and run it with /install -- this modifies the context menu to point to your program. Now when you right click edit with notepad++, it should open in new instance. to set it back to default, use /uninstall switch #NoTrayIcon Global $path = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\Notepad++', '') Global $context_reg = 'HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shellex\ContextMenuHandlers\', $guid If $CmdLineRaw = "/install" Or $CmdLineRaw = "/uninstall" Then If Not IsAdmin() Then MsgBox(0, 'error', 'Please re-run from command prompt with admin rights') Exit EndIf For $i = 1 To 10000 Local $var = RegEnumKey($context_reg, $i) If @error <> 0 Then ExitLoop If StringInStr($var, 'Notepad++') Then $guid = RegRead($context_reg & $var, '') Next If $guid = '' Then MsgBox(0, 'error', 'could not find ContextMenuHandler for Notepad++') Exit EndIf If $CmdLineRaw = "/install" Then RegWrite('HKEY_LOCAL_MACHINE64\SOFTWARE\Classes\CLSID\' & $guid & '\Settings', 'Path', 'REG_SZ', @ScriptFullPath) Else RegWrite('HKEY_LOCAL_MACHINE64\SOFTWARE\Classes\CLSID\' & $guid & '\Settings', 'Path', 'REG_SZ', $path & '\notepad++.exe') EndIf Exit EndIf Run($path & '\notepad++.exe -multiInst -nosession ' & $CmdLineRaw, $path, @SW_MAXIMIZE)
Mat Posted July 2, 2013 Author Posted July 2, 2013 Firstly, I recently rewrote this bit of code, you can find the new version >here. You aren't really using this properly, you probably wanted something like this: $Title = "NotepadNewInst" #include <File.au3> #include <CmdLine.au3> _CmdLine_Parse() NotepadNewInst() Func NotepadNewInst() Local $path = (@ScriptDir & '\') If CmdLine("") Then ConsoleWrite('notepad++.exe -multiInst -nosession ' & CmdLine("") & @LF) EndIf Exit EndFunc ;==>NotepadNewInst To be honest you are better off using the normal $CmdLine. This UDF was mostly designed to make more complicated command line applications. AutoIt Project Listing
DigitalFacade82 Posted July 6, 2013 Posted July 6, 2013 (edited) Damn I forgot to open my last post with well that certainly broke the fun n games (old as they are.....2011 haha) So the issue is when you are right clicking, it going to notepad++ directly so it is not executing your program at all. So you will need to modify the context menu to point to your program. so I made a some changes to your program. Compile it and place the exe wherever you want it. Then open command prompt with admin rights browse to where the exe location and run it with /install -- this modifies the context menu to point to your program. Not exactly. I am sorry the picture didn't come through before? It has now....and it seems to be rather large (sorry about that too), skydrive changed my share permissions? Looks like Microsoft have upped their security? As you will see in the screenshot it shrinks it to the very top left corner. No matter what you have its properties set as before executing, it ignores them every time and ends up shrunk.If I execute from my launcher script it always runs maximised. I just need my script to feed the variable %1 (the file I am right clicking) and parsing it to the main application executable. I am pretty familiar with Windows context menus. Mine is highly customised actually. From a normal command line notepad++.exe -multiInst -nosession <filename.extension> works just as it should, however in Windows explorer Notepad++ executable doesn't seem to listen when it is passed commands from the context menu? Firstly, I recently rewrote this bit of code, you can find the new version >here. You aren't really using this properly, you probably wanted something like this: $Title = "NotepadNewInst" #include <File.au3> #include <CmdLine.au3> _CmdLine_Parse() NotepadNewInst() Func NotepadNewInst() Local $path = (@ScriptDir & '\') If CmdLine("") Then ConsoleWrite('notepad++.exe -multiInst -nosession ' & CmdLine("") & @LF) EndIf Exit EndFunc ;==>NotepadNewInst To be honest you are better off using the normal $CmdLine. This UDF was mostly designed to make more complicated command line applications. Hi Mat, Thanks for your response. Actually what you have posted makes perfect sense now. I guess I am used to Run and (@comspec, I have not used ConsoleWrite except for switching in a hidden command prompt window for some tray buttons I made. Other than that nothing so I should probably familiarise myself with the Console commands. I come from a very DOS/Windows background, so I still have the tendency of doing what is comfortable or habit at the moment, like writing small applications still in batch....when I have all the wealth of AutoIT at my fingertips. Sad I know. You have made it so simplified; and I was making it damn complex by the look of things lol. Typical n00b that I am. Thanks will check out your thread when I have some time soon Cheers Edited July 6, 2013 by DigitalFacade82
TheSaint Posted July 7, 2013 Posted July 7, 2013 I haven't looked at your code much at all, but it seems to me, that your issue may be Working Directory related? Have you tried the same command string using a Shortcut file? Often command strings that work fine from the Command Prompt, won't work with other implementations, until you pass the Working Directory properly, perhaps with a Directory Change even. Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)
DigitalFacade82 Posted July 13, 2013 Posted July 13, 2013 (edited) I haven't looked at your code much at all, but it seems to me, that your issue may be Working Directory related? Have you tried the same command string using a Shortcut file? Often command strings that work fine from the Command Prompt, won't work with other implementations, until you pass the Working Directory properly, perhaps with a Directory Change even. Hi TheSaint, Um well that's the thing, the compiled script is actually run from the working directory. Notice the path is @Scriptdir that is basically the same as telling a batch file to cd "%~dp0" just before execution (my compiled script sits just inside Notepad++ directory next to notpad++.exe - note this is on Windows 7 not Windows 8, with Full Admin privileges....yes I probably should have with Req Admin rights but in all instances the execution DOES work). I don't believe it IS working directory related at all, I believe it is idiot related...meaning I got the syntax incorrect). But I also think the root of the problem leading to all this is definitely a bug in Notepad++ and not with my script. My script works otherwise. Meaning when it is launched; the exe works. Only when I compiled it to accept command line arguments it didn't. I now know why that is so and I can change it. Unfortunately launching from a shortcut is not going to fix my problem when it occurs at the right click context menu. Not being rude, but if you had read my post before responding you would know this. Also I have stated that Notepad++ works fine when it is fed command line arguments just not from the right click context menu. But yes your suggestion could be implemented in a very messy way by having a script launch a shortcut, but 1) that is not good practice at all and 2) that would still leave me back at square one in that how would I program a shortcut to accept command line arguments? I mean wouldn't it be easier to make a compiled exe accept arguments instead?.......and that is what my whole question was about in the first place. Apologies to the OP, I have not yet had the chance to implement what you have suggested, but thank you again. Edited July 13, 2013 by DigitalFacade82
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now