mihaijulien

Error: array variable has incorrect number of subscripts or subscript dimension range exceeded

23 posts in this topic

#1 ·  Posted

Hello,

I compiled a script I made that takes a command line parameter (the version of a .msi installer) when launched. The script was compiled with the /console option. The script (.au3) works fine but the executable returns  the following error:  

Error: array variable has incorrect number of subscripts or subscript dimension range exceeded

 

Share this post


Link to post
Share on other sites



#2 ·  Posted

The script doesn't work fine as you can see so there must be a condition that a function doesn't return an expected Array and you aren't testing for that condition.

Without a script we won't be able to assist.

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#3 ·  Posted

Here is the code:

#RequireAdmin

#include <FileConstants.au3>
#include <WinAPIShPath.au3>
#include "UDF\log4a.au3"

Opt("WinTitleMatchMode",2)

Global $defaultLocation = "C:\Program Files\MyApp\" & $CmdLine
Global $CmdLine = _WinAPI_CommandLineToArgv($CmdLineRaw)

Install()
$processes = _MyProcessList("MyApp")
If ProcessExists($processes[1]) Then
   LogInfo("App service started succesfully")
EndIf
_ProcessCloseEx($processes[1]) ;kill App & child processes

Func Install()

   Local $hWnd = "MyApp " & $CmdLine[2] &" Setup"
   Local $installer = "myapp-win-installer-" & $CmdLine[2] &".msi"

   ShellExecute($installer,"",@ScriptDir & "\installers")
   If @error Then
      LogInfo("Error when starting the installer")
      Return
   EndIf

   While Not ControlCommand($hWnd,"","[Text:&Next >]", "IsEnabled",'')
      Sleep(500)
      ;if the app is already installed, close the install wizard
      If ControlGetText($hWnd,"","[Text:Remove Installation]") Then
         LogError("Error: MyApp is already installed")
         Sleep(1000)
         WinClose($hWnd)
         Return
      EndIf

   WEnd

   ControlClick($hWnd,"","[CLASS:Button; INSTANCE:1]") ;first Next ;1572
   Local $counter = 0
   For $counter = 0 to 1
      Send("{TAB}")
      Sleep(100)
   Next
   Send("{UP}") ;accept the terms in the License Agreement ;57
   Sleep(100)
   ControlClick($hWnd,"","[CLASS:Button; INSTANCE:1]") ; Next ;1572
   Sleep(500)
   ControlClick($hWnd,"","[CLASS:Button; INSTANCE:5]") ; uncheck app start ;3281
   Sleep(500)
   ;install the app at the default location
   ControlClick($hWnd,"","[CLASS:Button; INSTANCE:1]") ; Next ;1572
   Sleep(500)
   If WinExists($hWnd, "Port Conflict Found") Then
      ControlClick($hWnd, "","[CLASS:Button; INSTANCE:4]")
      Sleep(500)
      ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
   EndIf

   WinWaitActive("MyApp Test")
   ControlClick("MyApp Test","","[CLASS:Button; INSTANCE:1]") ;Ok on the test


   ; wait the install successful UI
   While 1
      $var = ControlGetText($hWnd, "", "[Text:&Finish]")

      If $var == "&Finish" Then

      ControlClick($hWnd,"","[CLASS:Button; INSTANCE:1]") ;Finish

         ExitLoop
      EndIf
      Sleep(1000)
   WEnd

EndFunc

;kill processes
Func _ProcessCloseEx($sPID)
    If IsString($sPID) Then $sPID = ProcessExists($sPID)
    If Not $sPID Then Return SetError(1, 0, 0)

    Return Run(@ComSpec & " /c taskkill /F /PID " & $sPID & " /T", @SystemDir, @SW_HIDE)
 EndFunc

 ;retrieve processes using partial name string as parameter
 Func _MyProcessList($str)

    Local $alist = ProcessList(), $ret
    For $1 = 0 To UBound($alist) - 1
        If StringInStr($alist[$1][0], $str) Then $ret &= $alist[$1][0] & '|'
    Next

    Return StringSplit(StringTrimRight($ret, 1), '|')

EndFunc

The .au3 works fine.

Share this post


Link to post
Share on other sites

#4 ·  Posted

Can't test as I don't haave the include you use, but my guess is that $ret remains empty in Func _MyProcessList , hence not returning an Array, thus triggering an error in the next statement testing for $processes[1]. Does this work?

Func _MyProcessList($str)

    Local $alist = ProcessList(), $ret="|"
    For $1 = 0 To UBound($alist) - 1
        If StringInStr($alist[$1][0], $str) Then $ret &= $alist[$1][0] & '|'
    Next

    Return StringSplit(StringTrimRight($ret, 1), '|')

EndFunc   ;==>_MyProcessList

 


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#5 ·  Posted

Hello,

I don't think it's relevant what it's in the UDF folder that I included, but here it is attached. The script above works just fine when not compiled.

 

UDF.7z

Share this post


Link to post
Share on other sites

#7 ·  Posted

I am unsure what the intent of the concatenation of the first line should do as $CmdLine is an Array.

I actually think the second line in this part could also be giving problems when $CmdLineRaw is empty.
Also wouldn't use $CmdLine as that in an internal constant but something else like:

Global $defaultLocation = "C:\Program Files\MyApp\" & $CmdLine
Global $sCmdLine = _WinAPI_CommandLineToArgv($CmdLineRaw)
if UBound($sCmdLine) < 3 then
    ; there are not enough parameters specified
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $CmdLineRaw = ' & $CmdLineRaw & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
EndIf

;~ Install()
$processes = _MyProcessList("MyApp")
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $processes[1] = ' & $processes[1] & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
If ProcessExists($processes[1]) Then
;~  LogInfo("App service started succesfully")
EndIf
_ProcessCloseEx($processes[1]) ;kill App & child processes

Func Install()

    Local $hWnd = "MyApp " & $sCmdLine[2] & " Setup"
    Local $installer = "myapp-win-installer-" & $sCmdLine[2] & ".msi"

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#8 ·  Posted

The script works just fine when it isn't compiled. When launching the .exe, I have the error from the attached file.

It's pretty strange.

error.png

Share this post


Link to post
Share on other sites

#9 ·  Posted

Have you tried my suggestions, as repeating what I already know doesn't help much. ...  and no, it is not per se strange that it works uncompiled and erros compiled when the issue is around commandline parameters as with the uncompiled version, there always are parameters supplied to run the script.

So pls start testing and providing more exact information.

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Simple question:

How exactly do you run the console exe, and how exactly to you run the app exe?

I'm assuming that you are expecting the console parameters you use to be compiled into the app exe...which will not happen.

 

Edit, if the above is not related...you should update your script to not assume that arrays are created, and have the proper amount of subscripts...you should include error handling that validates the UBound of all dimensions....such as, if it's not as large as you expect, throw a msgbox stating where in the script you are, so you can fix it...then exit.

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#11 ·  Posted

Well, I open a cmd and I type "InstallScript.au3 5.0". I launch the executable in the same way: "InstallScript.exe 5.0". The first works, the second doesn't. I'm still trying to figure out what might be the problem.

Share this post


Link to post
Share on other sites

#12 ·  Posted

Good lucky:

#RequireAdmin
Opt("TrayAutoPause", 0)
Opt("WinTitleMatchMode", 2)

Global $CmdLine = _WinAPI_CommandLineToArgv($CmdLineRaw)
If @error Then Exit _WriteLog("! Not enter comnand line!", @ScriptLineNumber)

Install()

Global $processes = _MyProcessList("MyApp")
If Not @error And IsArray($processes) Then
    If ProcessExists($processes[1]) Then
        _WriteLog("+ App service started succesfully", @ScriptLineNumber)
    EndIf
    _ProcessCloseEx($processes[1])
Else
    _WriteLog("! App service not started", @ScriptLineNumber)
EndIf

Func Install()
    Local $hWnd = "MyApp " & $CmdLine[2] & " Setup"
    Local $installer = "myapp-win-installer-" & $CmdLine[2] & ".msi"
    ShellExecute($installer, "", @ScriptDir & "\installers")
    If @error Then
        _WriteLog("Error when starting the installer", @ScriptLineNumber)
        Return
    EndIf
    While (Not ControlCommand($hWnd, "", "[Text:&Next >]", "IsEnabled", ''))
        Sleep(500)
        If ControlGetText($hWnd, "", "[Text:Remove Installation]") Then
            _WriteLog("Error: MyApp is already installed", @ScriptLineNumber)
            Sleep(1000)
            WinClose($hWnd)
            Return
        EndIf
    WEnd
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Local $counter = 0
    For $counter = 0 To 1
        Send("{TAB}")
        Sleep(100)
    Next
    Send("{UP}")
    Sleep(100)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Sleep(500)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:5]")
    Sleep(500)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Sleep(500)
    If WinExists($hWnd, "Port Conflict Found") Then
        ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:4]")
        Sleep(500)
        ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    EndIf
    WinWaitActive("MyApp Test")
    ControlClick("MyApp Test", "", "[CLASS:Button; INSTANCE:1]")
    Local $var
    While 1
        $var = ControlGetText($hWnd, "", "[Text:&Finish]")
        If $var == "&Finish" Then
            ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
            ExitLoop
        EndIf
        Sleep(1000)
    WEnd
EndFunc   ;==>Install
Func _ProcessCloseEx($sPID)
    If IsString($sPID) Then $sPID = ProcessExists($sPID)
    If Not $sPID Then Return SetError(1, 0, 0)
    Return Run(@ComSpec & " /c taskkill /F /PID " & $sPID & " /T", @SystemDir, @SW_HIDE)
EndFunc   ;==>_ProcessCloseEx
Func _MyProcessList($str)
    Local $alist = ProcessList(), $ret
    If $alist[0][0] <> 0 Then
        For $1 = 0 To UBound($alist) - 1
            If StringInStr($alist[$1][0], $str) Then $ret &= $alist[$1][0] & '|'
        Next
        Return StringSplit(StringTrimRight($ret, 1), '|')
    EndIf
    Return SetError(1, 0, "")
EndFunc   ;==>_MyProcessList
;
Func _WinAPI_GetString($pString, $bUnicode = True)
    Local $iLength = _WinAPI_StrLen($pString, $bUnicode)
    If @error Or Not $iLength Then Return SetError(@error + 10, @extended, '')
    Local $tString = DllStructCreate(__Iif($bUnicode, 'wchar', 'char') & '[' & ($iLength + 1) & ']', $pString)
    If @error Then Return SetError(@error, @extended, '')
    Return SetExtended($iLength, DllStructGetData($tString, 1))
EndFunc   ;==>_WinAPI_GetString
Func _WinAPI_StrLen($pString, $bUnicode = True)
    Local $W = ''
    If $bUnicode Then $W = 'W'
    Local $aRet = DllCall('kernel32.dll', 'int', 'lstrlen' & $W, 'struct*', $pString)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aRet[0]
EndFunc   ;==>_WinAPI_StrLen
Func __Iif($bTest, $vTrue, $vFalse)
    Return $bTest ? $vTrue : $vFalse
EndFunc   ;==>__Iif
Func _WinAPI_CommandLineToArgv($sCmd)
    Local $aResult[1] = [0]
    $sCmd = StringStripWS($sCmd, 1 + 2)
    If Not $sCmd Then
        Return $aResult
    EndIf
    Local $aRet = DllCall('shell32.dll', 'ptr', 'CommandLineToArgvW', 'wstr', $sCmd, 'int*', 0)
    If @error Or Not $aRet[0] Or (Not $aRet[2]) Then Return SetError(@error + 10, @extended, 0)
    Local $tPtr = DllStructCreate('ptr[' & $aRet[2] & ']', $aRet[0])
    Dim $aResult[$aRet[2] + 1] = [$aRet[2]]
    For $i = 1 To $aRet[2]
        $aResult[$i] = _WinAPI_GetString(DllStructGetData($tPtr, 1, $i))
    Next
    DllCall("kernel32.dll", "handle", "LocalFree", "handle", $aRet[0])
    Return $aResult
EndFunc   ;==>_WinAPI_CommandLineToArgv
Func _WriteLog($iLine, $sLine = "")
    Local $iTime = ($sLine == "") ? @HOUR & @MIN & @SEC & ": " & $iLine : @HOUR & @MIN & @SEC & "_ScriptLine-" & $sLine & ": " & $iLine
    FileWriteLine(@ScriptName & ".log", $iTime)
    ConsoleWrite($iTime & @CRLF)
EndFunc   ;==>_WriteLog

 


Regards,
 

Share this post


Link to post
Share on other sites

#13 ·  Posted

1 hour ago, Trong said:

Good lucky:

#RequireAdmin
Opt("TrayAutoPause", 0)
Opt("WinTitleMatchMode", 2)

Global $CmdLine = _WinAPI_CommandLineToArgv($CmdLineRaw)
If @error Then Exit _WriteLog("! Not enter comnand line!", @ScriptLineNumber)

Install()

Global $processes = _MyProcessList("MyApp")
If Not @error And IsArray($processes) Then
    If ProcessExists($processes[1]) Then
        _WriteLog("+ App service started succesfully", @ScriptLineNumber)
    EndIf
    _ProcessCloseEx($processes[1])
Else
    _WriteLog("! App service not started", @ScriptLineNumber)
EndIf

Func Install()
    Local $hWnd = "MyApp " & $CmdLine[2] & " Setup"
    Local $installer = "myapp-win-installer-" & $CmdLine[2] & ".msi"
    ShellExecute($installer, "", @ScriptDir & "\installers")
    If @error Then
        _WriteLog("Error when starting the installer", @ScriptLineNumber)
        Return
    EndIf
    While (Not ControlCommand($hWnd, "", "[Text:&Next >]", "IsEnabled", ''))
        Sleep(500)
        If ControlGetText($hWnd, "", "[Text:Remove Installation]") Then
            _WriteLog("Error: MyApp is already installed", @ScriptLineNumber)
            Sleep(1000)
            WinClose($hWnd)
            Return
        EndIf
    WEnd
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Local $counter = 0
    For $counter = 0 To 1
        Send("{TAB}")
        Sleep(100)
    Next
    Send("{UP}")
    Sleep(100)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Sleep(500)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:5]")
    Sleep(500)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Sleep(500)
    If WinExists($hWnd, "Port Conflict Found") Then
        ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:4]")
        Sleep(500)
        ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    EndIf
    WinWaitActive("MyApp Test")
    ControlClick("MyApp Test", "", "[CLASS:Button; INSTANCE:1]")
    Local $var
    While 1
        $var = ControlGetText($hWnd, "", "[Text:&Finish]")
        If $var == "&Finish" Then
            ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
            ExitLoop
        EndIf
        Sleep(1000)
    WEnd
EndFunc   ;==>Install
Func _ProcessCloseEx($sPID)
    If IsString($sPID) Then $sPID = ProcessExists($sPID)
    If Not $sPID Then Return SetError(1, 0, 0)
    Return Run(@ComSpec & " /c taskkill /F /PID " & $sPID & " /T", @SystemDir, @SW_HIDE)
EndFunc   ;==>_ProcessCloseEx
Func _MyProcessList($str)
    Local $alist = ProcessList(), $ret
    If $alist[0][0] <> 0 Then
        For $1 = 0 To UBound($alist) - 1
            If StringInStr($alist[$1][0], $str) Then $ret &= $alist[$1][0] & '|'
        Next
        Return StringSplit(StringTrimRight($ret, 1), '|')
    EndIf
    Return SetError(1, 0, "")
EndFunc   ;==>_MyProcessList
;
Func _WinAPI_GetString($pString, $bUnicode = True)
    Local $iLength = _WinAPI_StrLen($pString, $bUnicode)
    If @error Or Not $iLength Then Return SetError(@error + 10, @extended, '')
    Local $tString = DllStructCreate(__Iif($bUnicode, 'wchar', 'char') & '[' & ($iLength + 1) & ']', $pString)
    If @error Then Return SetError(@error, @extended, '')
    Return SetExtended($iLength, DllStructGetData($tString, 1))
EndFunc   ;==>_WinAPI_GetString
Func _WinAPI_StrLen($pString, $bUnicode = True)
    Local $W = ''
    If $bUnicode Then $W = 'W'
    Local $aRet = DllCall('kernel32.dll', 'int', 'lstrlen' & $W, 'struct*', $pString)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aRet[0]
EndFunc   ;==>_WinAPI_StrLen
Func __Iif($bTest, $vTrue, $vFalse)
    Return $bTest ? $vTrue : $vFalse
EndFunc   ;==>__Iif
Func _WinAPI_CommandLineToArgv($sCmd)
    Local $aResult[1] = [0]
    $sCmd = StringStripWS($sCmd, 1 + 2)
    If Not $sCmd Then
        Return $aResult
    EndIf
    Local $aRet = DllCall('shell32.dll', 'ptr', 'CommandLineToArgvW', 'wstr', $sCmd, 'int*', 0)
    If @error Or Not $aRet[0] Or (Not $aRet[2]) Then Return SetError(@error + 10, @extended, 0)
    Local $tPtr = DllStructCreate('ptr[' & $aRet[2] & ']', $aRet[0])
    Dim $aResult[$aRet[2] + 1] = [$aRet[2]]
    For $i = 1 To $aRet[2]
        $aResult[$i] = _WinAPI_GetString(DllStructGetData($tPtr, 1, $i))
    Next
    DllCall("kernel32.dll", "handle", "LocalFree", "handle", $aRet[0])
    Return $aResult
EndFunc   ;==>_WinAPI_CommandLineToArgv
Func _WriteLog($iLine, $sLine = "")
    Local $iTime = ($sLine == "") ? @HOUR & @MIN & @SEC & ": " & $iLine : @HOUR & @MIN & @SEC & "_ScriptLine-" & $sLine & ": " & $iLine
    FileWriteLine(@ScriptName & ".log", $iTime)
    ConsoleWrite($iTime & @CRLF)
EndFunc   ;==>_WriteLog

 

Works perfectly when running the .au3, after I compile it (x64) it no longer works, same error. (but this time the error is on Line 17). :/

Share this post


Link to post
Share on other sites

#14 ·  Posted

Funny how you seem to ignore the pointers I have given you and you persisting to repeat it isn't working.
Just for the last time: Have you tested the possible solution I gave? 
Do you understand what I have tried to tell you?
Do you have any question about it?

Jos
 


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#15 ·  Posted

9 minutes ago, Jos said:

Funny how you seem to ignore the pointers I have given you and you persisting to repeat it isn't working.
Just for the last time: Have you tested the possible solution I gave? 
Do you understand what I have tried to tell you?
Do you have any question about it?

Jos
 

Sorry I didn't reply, but yes, I tried my scripts with your suggestions (changing the default $CmdLine to $sCmdLine.

Share this post


Link to post
Share on other sites

#16 ·  Posted

.... and?

Did you get the console prompt? ( Maybe you need to change that to a MSGBOX() so it always shows!
You really need to learn to start providing information and help testing when you want your issue to be resolved! ;)

Try replacing that added test with this version:

Global $defaultLocation = "C:\Program Files\MyApp\" & $CmdLine
Global $sCmdLine = _WinAPI_CommandLineToArgv($CmdLineRaw)
if UBound($sCmdLine) < 3 then
    MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @CRLF & '$CmdLineRaw' & @CRLF & @CRLF & 'Return:' & @CRLF & $CmdLineRaw)
    Exit
EndIf

The script will exit after showing the msgbox() in case there are not enough parameters provided.

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#17 ·  Posted

Bad script:

#RequireAdmin
Opt("TrayAutoPause", 0)
Opt("WinTitleMatchMode", 2)


Global $sCmdLineRaw = @Compiled ? $CmdLineRaw : "" ;StringReplace($CmdLineRaw, '/ErrorStdOut "' & @ScriptFullPath & '"    ', "")
Global $xCmdLine = _WinAPI_CommandLineToArgv($sCmdLineRaw)
If @error Or ($xCmdLine[0] = 0) Then Exit _WriteLog("! Not enter comnand line!", @ScriptLineNumber)
If $xCmdLine[0] < 2 Then Exit _WriteLog("! You enter not corect comnand line!", @ScriptLineNumber)

Install()

Global $processes = _MyProcessList("MyApp")
If Not @error And IsArray($processes) Then
    If ProcessExists($processes[1]) Then
        _WriteLog("+ App service started succesfully", @ScriptLineNumber)
    EndIf
    _ProcessCloseEx($processes[1])
Else
    _WriteLog("! Your App service not started", @ScriptLineNumber)
EndIf

Func Install()
    Local $hWnd = "MyApp " & $xCmdLine[2] & " Setup"
    Local $installer = "myapp-win-installer-" & $xCmdLine[2] & ".msi"
    If FileExists($installer) Then
        ShellExecute($installer, "", @ScriptDir & "\installers")
        If @error Then
            _WriteLog("Error when starting the installer", @ScriptLineNumber)
            Return
        EndIf
    Else
        Return _WriteLog("Error! installer file not Exists!", @ScriptLineNumber)
    EndIf
    While (Not ControlCommand($hWnd, "", "[Text:&Next >]", "IsEnabled", ''))
        Sleep(500)
        If ControlGetText($hWnd, "", "[Text:Remove Installation]") Then
            _WriteLog("Error: MyApp is already installed", @ScriptLineNumber)
            Sleep(1000)
            WinClose($hWnd)
            Return
        EndIf
    WEnd
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Local $counter = 0
    For $counter = 0 To 1
        Send("{TAB}")
        Sleep(100)
    Next
    Send("{UP}")
    Sleep(100)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Sleep(500)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:5]")
    Sleep(500)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Sleep(500)
    If WinExists($hWnd, "Port Conflict Found") Then
        ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:4]")
        Sleep(500)
        ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    EndIf
    WinWaitActive("MyApp Test")
    ControlClick("MyApp Test", "", "[CLASS:Button; INSTANCE:1]")
    Local $var
    While 1
        $var = ControlGetText($hWnd, "", "[Text:&Finish]")
        If $var == "&Finish" Then
            ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
            ExitLoop
        EndIf
        Sleep(1000)
    WEnd
EndFunc   ;==>Install
Func _ProcessCloseEx($sPID)
    If IsString($sPID) Then $sPID = ProcessExists($sPID)
    If Not $sPID Then Return SetError(1, 0, 0)
    Return Run(@ComSpec & " /c taskkill /F /PID " & $sPID & " /T", @SystemDir, @SW_HIDE)
EndFunc   ;==>_ProcessCloseEx
Func _MyProcessList($str)
    Local $alist = ProcessList(), $ret
    If $alist[0][0] <> 0 Then
        For $1 = 0 To UBound($alist) - 1
            If StringInStr($alist[$1][0], $str) Then $ret &= $alist[$1][0] & '|'
        Next
        Return StringSplit(StringTrimRight($ret, 1), '|')
    EndIf
    Return SetError(1, 0, "")
EndFunc   ;==>_MyProcessList
;
Func _WinAPI_GetString($pString, $bUnicode = True)
    Local $iLength = _WinAPI_StrLen($pString, $bUnicode)
    If @error Or Not $iLength Then Return SetError(@error + 10, @extended, '')
    Local $tString = DllStructCreate(__Iif($bUnicode, 'wchar', 'char') & '[' & ($iLength + 1) & ']', $pString)
    If @error Then Return SetError(@error, @extended, '')
    Return SetExtended($iLength, DllStructGetData($tString, 1))
EndFunc   ;==>_WinAPI_GetString
Func _WinAPI_StrLen($pString, $bUnicode = True)
    Local $W = ''
    If $bUnicode Then $W = 'W'
    Local $aRet = DllCall('kernel32.dll', 'int', 'lstrlen' & $W, 'struct*', $pString)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aRet[0]
EndFunc   ;==>_WinAPI_StrLen
Func __Iif($bTest, $vTrue, $vFalse)
    Return $bTest ? $vTrue : $vFalse
EndFunc   ;==>__Iif
Func _WinAPI_CommandLineToArgv($sCmd)
    Local $aResult[1] = [0]
    $sCmd = StringStripWS($sCmd, 1 + 2)
    If Not $sCmd Then
        Return $aResult
    EndIf
    Local $aRet = DllCall('shell32.dll', 'ptr', 'CommandLineToArgvW', 'wstr', $sCmd, 'int*', 0)
    If @error Or Not $aRet[0] Or (Not $aRet[2]) Then Return SetError(@error + 10, @extended, 0)
    Local $tPtr = DllStructCreate('ptr[' & $aRet[2] & ']', $aRet[0])
    Dim $aResult[$aRet[2] + 1] = [$aRet[2]]
    For $i = 1 To $aRet[2]
        $aResult[$i] = _WinAPI_GetString(DllStructGetData($tPtr, 1, $i))
    Next
    DllCall("kernel32.dll", "handle", "LocalFree", "handle", $aRet[0])
    Return $aResult
EndFunc   ;==>_WinAPI_CommandLineToArgv
Func _WriteLog($iLine, $sLine = "")
    Local $iTime = ($sLine == "") ? @HOUR & @MIN & @SEC & ": " & $iLine : @HOUR & @MIN & @SEC & "_ScriptLine-" & $sLine & ": " & $iLine
    FileWriteLine(@ScriptName & ".log", $iTime)
    ConsoleWrite($iTime & @CRLF)
    MsgBox(48 + 262144, "Debug", $iLine & @CRLF & "This Notice On Line: " & $sLine)
EndFunc   ;==>_WriteLog


 


Regards,
 

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

1 hour ago, Trong said:

Bad script:

#RequireAdmin
Opt("TrayAutoPause", 0)
Opt("WinTitleMatchMode", 2)


Global $sCmdLineRaw = @Compiled ? $CmdLineRaw : "" ;StringReplace($CmdLineRaw, '/ErrorStdOut "' & @ScriptFullPath & '"    ', "")
Global $xCmdLine = _WinAPI_CommandLineToArgv($sCmdLineRaw)
If @error Or ($xCmdLine[0] = 0) Then Exit _WriteLog("! Not enter comnand line!", @ScriptLineNumber)
If $xCmdLine[0] < 2 Then Exit _WriteLog("! You enter not corect comnand line!", @ScriptLineNumber)

Install()

Global $processes = _MyProcessList("MyApp")
If Not @error And IsArray($processes) Then
    If ProcessExists($processes[1]) Then
        _WriteLog("+ App service started succesfully", @ScriptLineNumber)
    EndIf
    _ProcessCloseEx($processes[1])
Else
    _WriteLog("! Your App service not started", @ScriptLineNumber)
EndIf

Func Install()
    Local $hWnd = "MyApp " & $xCmdLine[2] & " Setup"
    Local $installer = "myapp-win-installer-" & $xCmdLine[2] & ".msi"
    If FileExists($installer) Then
        ShellExecute($installer, "", @ScriptDir & "\installers")
        If @error Then
            _WriteLog("Error when starting the installer", @ScriptLineNumber)
            Return
        EndIf
    Else
        Return _WriteLog("Error! installer file not Exists!", @ScriptLineNumber)
    EndIf
    While (Not ControlCommand($hWnd, "", "[Text:&Next >]", "IsEnabled", ''))
        Sleep(500)
        If ControlGetText($hWnd, "", "[Text:Remove Installation]") Then
            _WriteLog("Error: MyApp is already installed", @ScriptLineNumber)
            Sleep(1000)
            WinClose($hWnd)
            Return
        EndIf
    WEnd
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Local $counter = 0
    For $counter = 0 To 1
        Send("{TAB}")
        Sleep(100)
    Next
    Send("{UP}")
    Sleep(100)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Sleep(500)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:5]")
    Sleep(500)
    ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    Sleep(500)
    If WinExists($hWnd, "Port Conflict Found") Then
        ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:4]")
        Sleep(500)
        ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
    EndIf
    WinWaitActive("MyApp Test")
    ControlClick("MyApp Test", "", "[CLASS:Button; INSTANCE:1]")
    Local $var
    While 1
        $var = ControlGetText($hWnd, "", "[Text:&Finish]")
        If $var == "&Finish" Then
            ControlClick($hWnd, "", "[CLASS:Button; INSTANCE:1]")
            ExitLoop
        EndIf
        Sleep(1000)
    WEnd
EndFunc   ;==>Install
Func _ProcessCloseEx($sPID)
    If IsString($sPID) Then $sPID = ProcessExists($sPID)
    If Not $sPID Then Return SetError(1, 0, 0)
    Return Run(@ComSpec & " /c taskkill /F /PID " & $sPID & " /T", @SystemDir, @SW_HIDE)
EndFunc   ;==>_ProcessCloseEx
Func _MyProcessList($str)
    Local $alist = ProcessList(), $ret
    If $alist[0][0] <> 0 Then
        For $1 = 0 To UBound($alist) - 1
            If StringInStr($alist[$1][0], $str) Then $ret &= $alist[$1][0] & '|'
        Next
        Return StringSplit(StringTrimRight($ret, 1), '|')
    EndIf
    Return SetError(1, 0, "")
EndFunc   ;==>_MyProcessList
;
Func _WinAPI_GetString($pString, $bUnicode = True)
    Local $iLength = _WinAPI_StrLen($pString, $bUnicode)
    If @error Or Not $iLength Then Return SetError(@error + 10, @extended, '')
    Local $tString = DllStructCreate(__Iif($bUnicode, 'wchar', 'char') & '[' & ($iLength + 1) & ']', $pString)
    If @error Then Return SetError(@error, @extended, '')
    Return SetExtended($iLength, DllStructGetData($tString, 1))
EndFunc   ;==>_WinAPI_GetString
Func _WinAPI_StrLen($pString, $bUnicode = True)
    Local $W = ''
    If $bUnicode Then $W = 'W'
    Local $aRet = DllCall('kernel32.dll', 'int', 'lstrlen' & $W, 'struct*', $pString)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aRet[0]
EndFunc   ;==>_WinAPI_StrLen
Func __Iif($bTest, $vTrue, $vFalse)
    Return $bTest ? $vTrue : $vFalse
EndFunc   ;==>__Iif
Func _WinAPI_CommandLineToArgv($sCmd)
    Local $aResult[1] = [0]
    $sCmd = StringStripWS($sCmd, 1 + 2)
    If Not $sCmd Then
        Return $aResult
    EndIf
    Local $aRet = DllCall('shell32.dll', 'ptr', 'CommandLineToArgvW', 'wstr', $sCmd, 'int*', 0)
    If @error Or Not $aRet[0] Or (Not $aRet[2]) Then Return SetError(@error + 10, @extended, 0)
    Local $tPtr = DllStructCreate('ptr[' & $aRet[2] & ']', $aRet[0])
    Dim $aResult[$aRet[2] + 1] = [$aRet[2]]
    For $i = 1 To $aRet[2]
        $aResult[$i] = _WinAPI_GetString(DllStructGetData($tPtr, 1, $i))
    Next
    DllCall("kernel32.dll", "handle", "LocalFree", "handle", $aRet[0])
    Return $aResult
EndFunc   ;==>_WinAPI_CommandLineToArgv
Func _WriteLog($iLine, $sLine = "")
    Local $iTime = ($sLine == "") ? @HOUR & @MIN & @SEC & ": " & $iLine : @HOUR & @MIN & @SEC & "_ScriptLine-" & $sLine & ": " & $iLine
    FileWriteLine(@ScriptName & ".log", $iTime)
    ConsoleWrite($iTime & @CRLF)
    MsgBox(48 + 262144, "Debug", $iLine & @CRLF & "This Notice On Line: " & $sLine)
EndFunc   ;==>_WriteLog


 

Ok, so using the script above, I get the following error, no matter what:

175628_ScriptLine-8: ! Not enter comnand line!

I'm not really sure if this is correct, xCmdLine[0] can't be 0 no matter what, as far as I get how things work with command line parameters.

 

Also, 

2 hours ago, Jos said:

.... and?

Did you get the console prompt? ( Maybe you need to change that to a MSGBOX() so it always shows!
You really need to learn to start providing information and help testing when you want your issue to be resolved! ;)

Try replacing that added test with this version:

Global $defaultLocation = "C:\Program Files\MyApp\" & $CmdLine
Global $sCmdLine = _WinAPI_CommandLineToArgv($CmdLineRaw)
if UBound($sCmdLine) < 3 then
    MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @CRLF & '$CmdLineRaw' & @CRLF & @CRLF & 'Return:' & @CRLF & $CmdLineRaw)
    Exit
EndIf

The script will exit after showing the msgbox() in case there are not enough parameters provided.

Jos

when using the above code, the script works fine when running the .au3 with the parameter, but the MsgBox pops when launching the .exe.

 

Untitled1.png

Edited by mihaijulien

Share this post


Link to post
Share on other sites

#19 ·  Posted

Yes of course it will popup!
I am have given you the appropriate information to resolve your problem and the ball is in your corner to do something with that provided information.
Let me know when you have questions.

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#20 ·  Posted

7 minutes ago, mihaijulien said:

Ok, so using the script above, I get the following error, no matter what:

175628_ScriptLine-8: ! Not enter comnand line!

I'm not really sure if this is correct, xCmdLine[0] can't be 0 no matter what, as far as I get how things work with command line parameters.

 

 

You did not understand your code and how it works!
Code works very well, only humans write wrong code and making it not work!

You have run the file directly and do not have any command passed on it!
Your code need to get the command parameters and work on it!

Do you still want the code to work for you? with no command line?


Regards,
 

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

  • Similar Content

    • TheAutomator
      By TheAutomator
      A fullscreen console with custom commands!

      Introduction:
      Hi everyone!
      This funny project started as a question in the help section:
      https://www.autoitscript.com/forum/topic/174404-edit-detect-key-before-updating-content/
      I'd like to share this script with everyone that is interested. 
       
      Why would I want it?
      You like the old style fullscreen console (like in the old day's), You can add custom commands, You can customize the font a lot more compared to cmd.exe, You can share ideas or add tweaks to the script.  
      What's next?
      I'm planning to add my own programming language to it!
      Its going to be implemented with an ActiveX COM dll.
      The syntax is going to be a bit like Lua I guess, any ideas are welcome!
       
      Todo:
      Add sounds. Make an icon / logo. Design a better grammar ( Backus-Naur-vorm: https://nl.wikipedia.org/wiki/Backus-Naur-vorm ). Make test "Console-Scripts" for it. Add a file type for script files ( like batch scripts ). Clean up and modify Console.Au3 content. Add an option to have to type a login password (maybe). Call neo   
      Thanks to:
      xxaviarxx: debugging, some ideas. jguinch: debugging, adding a bunch of tweaks and ideas. kylomas: debugging, new ideas.  
      Edits and updates:
      Added tab key Main edit has focus now on startup Made a pdf that explains the upcoming programming language (need feedback about it!)  
      Until the dll is ready you can have fun with what I already have, hope you like it!
      UDF can be downloaded from the attachments.
      Regards
       
      [The programming language part is been postponed]
      [It's been a while, made a custom recursive descent parser in AutoIt, language and updates will be uploaded soon!]
       
      TheAutomator
       
      Console.au3
      ConsoleScript.pdf
    • RC86
      By RC86
      Afternoon!
      Just a quick one as this has dawned on me recently when creating a little program.  When calling an executable I've created like Run(otherapp.exe) from within my executable is there a best practice to ensure things have gone smoothly?  So for example, should I monitor the PID to ensure it runs and closes within an acceptable timeframe?  Or within my other executable should I do EXITs in a certain way after functions and return codes etc?
      Could be a silly question but thought I'd ask.
    • BlazerV60
      By BlazerV60
      Hello all,
      I've written the code below which launches chrome in incognito mode and then proceeds to go to the autoit website.
      From my understanding, the Run() command is also supposed to output the PID number related to the application that got launched from the Run command.
      However when I run the below lines, it outputs a PID number that is different from the newly launched chrome browser's PID number, does anyone know why and possibly explain how I could retrieve the accurate PID number associated with the newly launched browser?
      Global $iPid = Run(@ComSpec & ' /c start chrome.exe https://www.autoitscript.com/forum/ -incognito' ,"", "") msgbox(0,"",$iPid) Thank you,
      Brian
    • hcI
      By hcI
      Hello I would like to know if there is a way to return a sentence in cmd when I launch from it (because I add arguments).
      For example, diskpart.exe which help to manage the key and hdd connected, when you launch it with the parameter "/f" the app return a sentence saying that it don't recognize the parameter "/f" and it return the sentence in the cmd where i started the application, not a new one.
      That's what I want to do but I couldn't find anything that would solve my problem on internet and on AutoIt like ConsoleWrite / ConsoleWriteError (don't work).
       
      Thanks
    • Duck
      By Duck
      I'm attempting to capture the output from the command line tool PSEXEC. I'm using AutoIT to run an instance of PSEXEC against a remote PC to audit Local Admins in my environment using net.exe (C:\Windows\System32> net localgroup administrators). However the usual trick I use to capture command line output does not appear to work well with PSEXEC, as the bottom portion of the output is missing from the return. Any ideas or recommendations are greatly appreciated.  
       
      Here is what I'm working with: 
      ;This script will read from a list of hosts and report who has local admin privileges on the machine #RequireAdmin Global $fileName = @ScriptDir & '\test.txt' ;hostlist, one host per line readHostList() ;Read list of hosts Func readHostList() Local $file = FileOpen($fileName, 0) While 1 $line = FileReadLine($file) If @error = -1 Then ExitLoop ConsoleWrite($line & @CRLF) ;MsgBox(0,0,$line) getLocalAdmins($line) WEnd FileClose($file) EndFunc ;run PSEXEC to list local admins Func getLocalAdmins($remotePC) Local $testFile = @ScriptDir &'\test234.txt' FileOpen($testFile, 1) Local $psexec = 'psexec \\' & $remotePC & ' net localgroup administrators' FileWriteLine($testFile, _RunCmd($psexec) ) FileClose($testFile) EndFunc ;Used to return CLI output Func _RunCmd($sCommand) Local $nPid = Run(@Comspec & " /c" & $sCommand, @SystemDir, @SW_Hide, 8), $sRet = "" If @Error then Return "ERROR:" & @ERROR ProcessWait($nPid) While 1 $sRet &= StdoutRead($nPID) If @error Or (Not ProcessExists ($nPid)) Then ExitLoop WEnd Return $sRet EndFunc  
      ## If i manually run the command on the remote PC via PSEXEC I will get the following output: 
      PsExec v2.11 - Execute processes remotely
      Copyright (C) 2001-2014 Mark Russinovich
      Sysinternals - www.sysinternals.com
      Starting net on PCNAME... on PCNAME...
      net exited on PCNAME with error code 0.
      -------------------------------------------------------------------------------
      admin
      Administrator
      Alias name     administrators
      Domain\Domain Admins
      Comment        Administrators have complete and unrestricted access to the computer/domain
      Members
      The command completed successfully.
       
      ## The returned output from running the above script is as follows:
      PsExec v2.11 - Execute processes remotely
      Copyright (C) 2001-2014 Mark Russinovich
      Sysinternals - www.sysinternals.com
      Alias name     administrators
      Connecting to PCNAME...
      Starting PSEXESVC service on PCNAME...
      Connecting with PsExec service on PCName...
      Starting net on PCNAME..
      net exited on PCNAME with error code 0.
       
      **Note to test this script PSEXEC must be in the system dir or the path in the script changed 
      PSEXEC tool: https://docs.microsoft.com/en-us/sysinternals/downloads/psexec