Jump to content
koolzerro

a little help with parsing parameters

Recommended Posts

koolzerro

Lets say we have this code:

If $CmdLine[0] = 0 Then

MsgBox(64, "Result", "No parameter was entered!")

Exit

EndIf

MsgBox(64, "Entry", $CmdLine[1])

if i compile the script i can sucessfully get the parameter parsed thru cmd but if i send the parameter again its opening another instance of my app... how can i make it to limit it to 1 instance but still parse parameters? I tried with "_Singleton" but if you limit the app to only one instance is not getting the parameters no more...

Share this post


Link to post
Share on other sites
Bilgus

so you want to pass new parameters to the currently running script?

 

Share this post


Link to post
Share on other sites
koolzerro
1 minute ago, Bilgus said:

so you want to pass new parameters to the currently running script?

 

yeah... thats exactly  what im trying to do but without onening another sentence of app.

Share this post


Link to post
Share on other sites
Bilgus
Posted (edited)

you are going to need some form of IPC (inter process communication)

easiest is just to register a message 

_WinAPI_RegisterWindowMessage ( $sMessage )

but that is limited to a very small amount of data

You could also use it in conjunction with a file of some sort to hold the data

@argumentum was just discussing it here

 

Edited by Bilgus

Share this post


Link to post
Share on other sites
Bilgus

there is no way to do it without opening another instance what you do is use _singleton to find out app is already running parse the new commandline options, pass them to original instance then close the new instance

Share this post


Link to post
Share on other sites
Bilgus
Posted (edited)

@koolzerro This should give you an idea of how to do it passing a message 

The other ways would use a similar logic

#include <WinAPI.au3>
Global $gsErr
Global $sBlank = "                                            ";Just to make messagebox wider
HotKeySet("{ESC}", _Exit_Now)

_Main()

;--------------------------------------------------------------------------------------

Func _Create_Message($sMessage)
    Local $iMsg = _WinAPI_RegisterWindowMessage($sMessage)
    If $iMsg = 0 Then $gsErr &= "IPC Message Creation Failure " & $sMessage & @CRLF
    Return $iMsg
EndFunc   ;==>_Create_Message

Func _Create_MessageHandler($iMsg, $sFunction)
    If $iMsg <> 0 Then
        Opt("GUIOnEventMode", 1)
        GUICreate(@ScriptName & "_IPC", 0, 0, 0, 0, 0, 0) ; create a top level window
        GUIRegisterMsg($iMsg, $sFunction)
    EndIf
EndFunc   ;==>_Create_MessageHandler

Func _Exit_Now()
    OnAutoItExitUnRegister("_Exit_Now")
    Exit
EndFunc   ;==>_Exit_Now

Func _IsCompiled() ;wakillon
    Return @Compiled
EndFunc   ;==>_IsCompiled

Func _Main()

    If _IsCompiled() Then ;We handle our Single instance here
        Local $iActMsg = _Create_Message("@ScriptFullPath" & "_msg")
        RunPassThrough($iActMsg)
        _Create_MessageHandler($iActMsg, Activated_Ext)
    EndIf

    OnAutoItExitRegister("_Exit_Now")

    While True
        Sleep(1000)
    WEnd

    Exit
EndFunc   ;==>_Main

Func Activated_Ext($hWnd, $iMsg, $wParam, $lParam)
    ;Message Posted from other instances
    MsgBox(0, "My Pid = " & @AutoItPID, $sBlank & @CRLF  & " Passed From Pid: " & int($lParam) & @CRLF & BinaryToString($wParam))
EndFunc   ;==>Activated_Ext

Func RunPassThrough($iActMsg = 0)
    Local $sSwitches = $CmdLineRaw
    MsgBox(0, "Pass Through " & @AutoItPID,  $sBlank & @CRLF & $sSwitches)
    RunSingleInstance($iActMsg)
EndFunc   ;==>RunPassThrough

Func RunSingleInstance($iActMsg)

    Local Const $HWND_BROADCAST = 0xFFFF
    If _Singleton_NOCHILD(@ScriptName, 1) = 0 Then
        ;If $CmdLine[0] > 1 And $CmdLine[1] <> "" Then ;Check Parameters here

            _WinAPI_PostMessage($HWND_BROADCAST, $iActMsg, StringToBinary("ASDF"), @AutoItPID) ;passes info back to original instance
            ;Take Note Of limit of 32 bits for wParam and lParam so 4 8-bit characters if you use text....

        ;;EndIf
        MsgBox(0, @AutoItPID, "Already running : Exiting")
        _Exit_Now() ;single instance of script ONLY
    EndIf
EndFunc   ;==>RunSingleInstance

;;You could just use the singleton function, I removed unneeded functionality from this version
Func _Singleton_NOCHILD($sOccurrenceName, $iFlag = 0) ;Valik
    ;Without SECURITY_ATTRIBUTES;;;
    Local Const $ERROR_ALREADY_EXISTS = 183
    Local $aHandle = DllCall("kernel32.dll", "handle", "CreateMutexW", "struct*", 0, "bool", 1, "wstr", $sOccurrenceName)
    If @error Then Return SetError(@error, @extended, 0)
    Local $aLastError = DllCall("kernel32.dll", "dword", "GetLastError")
    If @error Then Return SetError(@error, @extended, 0)
    If $aLastError[0] = $ERROR_ALREADY_EXISTS Then
        If BitAND($iFlag, 1) Then
            DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $aHandle[0])
            If @error Then Return SetError(@error, @extended, 0)
            Return SetError($aLastError[0], $aLastError[0], 0)
        Else
            Exit -1
        EndIf
    EndIf
    Return $aHandle[0]
EndFunc   ;==>_Singleton_NOCHILD

 

Edited by Bilgus
  • Thanks 1

Share this post


Link to post
Share on other sites
koolzerro

I love your example... your example solved my problem... thank you very much.

 

Share this post


Link to post
Share on other sites
Bilgus

great :) 

Just Make sure you remember you only get 32 bits in wParam and lParam so (FOUR  8-bit letters) in each or max of 0xFFFFFFFF in each if you use numbers

Also there is a system wide limit of User Level messages so don't go registering a bunch to get around the data limits

_WinAPI_RegisterWindowMessage($sMessage)

Share this post


Link to post
Share on other sites
koolzerro

I still have a problem... to make you understand what im trying to do i have to tell you what im trying to do :P. Im working at a folder protect, when you right click on a folder and choose add  to folder protect... to get that the folder path.

Share this post


Link to post
Share on other sites
Bilgus

ah see if you are doing something like that your best bet is some of the options from the IPC thread above

There are ways to use this method but it gets complicated fast

You are better off using one of those other methods

 

 

Share this post


Link to post
Share on other sites
Bilgus

there are also way to cheat like naming the window the file path and sharing a file either real or virtual let me look into creating a pidl it might end up being the least complicated now that I think of it

Share this post


Link to post
Share on other sites
koolzerro

is that complatated to get the path of a folder ? :D

Share this post


Link to post
Share on other sites
Bilgus

no its complicated to send it between processes 

Share this post


Link to post
Share on other sites
koolzerro

and btw your method of parsing parameters is working only from cmd from context menu is not....

Share this post


Link to post
Share on other sites
Bilgus

They Probably are in different places correct?

Quote

Local $iActMsg = _Create_Message("@ScriptFullPath" & "_msg")

^Change @scriptFullPath to something that matches between the two

Share this post


Link to post
Share on other sites
Bilgus

It's going to require more work than I have time for ATM here is the hacky but easy method 

 

you might keep the message sending part to give you notifications in your main instance or just close the secondary instance from your main instance...

Share this post


Link to post
Share on other sites
koolzerro

Thank you! Im at work now but ill have a look when i finish!

Share this post


Link to post
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

×