Jump to content

a little help with parsing parameters


Recommended Posts

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...

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

@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
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

 

Link to comment
Share on other sites

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...

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...