Jump to content
Sign in to follow this  
mihaijulien

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

Recommended Posts

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

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


SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

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

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

 


SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

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


SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

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

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


SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

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

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

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

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
 


SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


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

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


SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

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

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


SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By zoel
      Hello people, I have a script which calls CMD and executes the netstat command, but when I run it through SCITE the GUI opens but I have no output, How can I run the command as administrator?
      Here is my script so far
      #include <AutoItConstants.au3> #include <GUIConstantsEx.au3> #include <GuiEdit.au3> #include <ScrollBarsConstants.au3> #include <WindowsConstants.au3> #RequireAdmin Local $aWndPos Local $hWnd = GUICreate("Form2", 900, 420, -1, -1, Default + $WS_MAXIMIZE) GUISetBkColor(0xE4E4E4) Local $idFilemenu = GUICtrlCreateMenu("&File") Local $idExititem = GUICtrlCreateMenuItem("Exit", $idFilemenu) Local $idInput = GUICtrlCreateEdit("", 210, 10, 660, 360) GUICtrlSetResizing(-1, $GUI_DOCKBORDERS) GUICtrlSetFont(-1, 10, 400, Default, "COURIER NEW") Local $idButton = GUICtrlCreateButton("NetStat", 10, 10, 190, 25) GUICtrlSetResizing(-1, BitOR($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKWIDTH, $GUI_DOCKHEIGHT)) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $idExititem Exit Case $idButton GUICtrlSetData($idInput, _CmdInfo() & @CRLF) _GUICtrlEdit_Scroll($idInput, $SB_SCROLLCARET) _GUICtrlEdit_Scroll($idInput, $SB_SCROLLCARET) EndSwitch WEnd Func _CmdInfo($_sCmdInfo = "netstat /b") Local $iPID = Run(@ComSpec & " /c " & $_sCmdInfo, "", @SW_HIDE, BitOR($STDERR_CHILD, $STDOUT_CHILD)) ; Wait until the process has closed using the PID returned by Run. ProcessWaitClose($iPID) ; Read the Stdout stream of the PID returned by Run. This can also be done in a while loop. Look at the example for StderrRead. Local $sOutput = StringReplace(StdoutRead($iPID), @CRLF & @CRLF, @CRLF) Local $sOutErr = StringReplace(StderrRead($iPID), @CRLF & @CRLF, @CRLF) Local $sReult = $sOutput <> "" ? $sOutput : $sOutErr Return $sReult EndFunc  
    • By cruisepandey
      Hi There ! 
      I have a script here : 
       
      ;Launch CMD
      Run("C:\Windows\System32\cmd.exe")
      sleep(2000)
      $cmdHandle = WinActivate("C:\Windows\System32\cmd.exe")
      Sleep(2000)
      ;Sending document
      ControlSend($cmdHandle, "", "", "ftp" & @CRLF)
      ControlSend($cmdHandle, "", "", "open" & @CRLF)
      Sleep(2000)
      ControlSend($cmdHandle, "", "", "first command" & @CRLF)
      Sleep(2000)
      ControlSend($cmdHandle, "", "", "second-coomand" & @CRLF)
       
      first-command and second-command I can't provide cause it's internal. I have complied this .au3 file into an exe and it does the work. But I need to invoke this with Java. Java code I have tried is : 
       
          ProcessBuilder pb = new ProcessBuilder("C:\\Users\\username\\eclipse-workspace\\Examples\\src\\com\\own\\examples\\etc.exe");
          pb.start();
          Thread.sleep(5000);
       
      Through java it just launches the cmd and nothing happens after that. Please help !!
    • By Chimp
      I'm trying to drive a command prompt by sending instructions via a NamedPipe.
      This way you can (should) be able to send commands to the command prompt and at the same time "view" the result in the same window.
      This is not allowed if you run a command prompt with "opt_flag" parameters (redirected streams) because this will disable StdOut on the cmd itself.
      This small (trivial) snippet works for the first command sent to the cmd, but further submissions will fail.
      Maybe the problem is in how I use the run () command to start a new cmd with the StdIn redirect from the NamedPipe. It seems that the generated cmd will close automatically after the first reception of the command via NamedPipe.
      suggestions on how to make it work are welcome
      thanks
      #include <NamedPipes.au3> #include <WinAPI.au3> ; Creates an instance of a named pipe Global $sPipeName = "\\.\pipe\pipename" Global $hPipe = _NamedPipes_CreateNamedPipe($sPipeName, 1, 1) MsgBox(0, "Debug", "Pipe created. Now open a CMD") ; run a cmd with only StdIn redirected (StdIn data incoming from a pipe) Global $hCMD = Run(@ComSpec & " /K cmd < " & $sPipeName & @CRLF, "c:\") ; ok? MsgBox(0, "Debug", "now Send a command to the cmd via a NamedPipe") _StdInPipeWrite("dir" & @CRLF) MsgBox(0, 'Debug', "further commands will fail" & @CRLF & "now send command 'dir c:\windows'") $sMessage = "Dir c:\windows" & @CRLF _StdInPipeWrite($sMessage) MsgBox(0, 'Debug', "send another command (will also fail)" & @CRLF & "now send command 'echo Hello'") _StdInPipeWrite("echo Hello" & @CRLF) MsgBox(0, "Debug", "end of test") ProcessClose($hCMD) Func _StdInPipeWrite($sMessage) ; =============================================================================================================================== ; This function writes a message to the pipe ; =============================================================================================================================== Local $iWritten, $iBuffer, $pBuffer, $tBuffer $iBuffer = StringLen($sMessage) + 1 $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]") $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tBuffer, "Text", $sMessage) If Not _WinAPI_WriteFile( _ $hPipe, _ ; ...... Handle to the file to be written $pBuffer, _ ; .... Pointer to the buffer containing the data to be written $iBuffer, _ ; .... Number of bytes to be written to the file $iWritten, _ ; ... The number of bytes written 0 _ ; ............ [optional] A $tagOVERLAPPED structure or a pointer to it ) Then ConsoleWrite("WriteMsg: _WinAPI_WriteFile failed" & @CRLF & _WinAPI_GetLastErrorMessage()) Else ConsoleWrite("WriteMsg: write OK" & @CRLF & _WinAPI_GetLastErrorMessage() & @CRLF) EndIf EndFunc ;==>_StdInPipeWrite  
    • By Burgs
      Greetings,
        I would like to be able to write a script to send commands to the console for creation of Gstreamer pipelines.  I was thinking of something similar to this:
      Local $iPID = Run("C:\Windows\System32\cmd", "", @SW_MAXIMIZE) ;THIS OPENS THE CONSOLE...!!! if $iPID == 0 Then ConsoleWrite(@CRLF & "I DID NOT OPEN CMD...error: " & @error & @CRLF) if $iPID <> 0 Then ConsoleWrite(@CRLF & "I OPENED CMD...!!!" & @CRLF) $hCmd = WinGetHandle("C:\WINDOWS\system32\cmd.exe") if $hCmd <> 0 Then WinActivate($hCmd) ;ensure command console is active... $sOutput = Send("cd C:\gstreamer\1.0\x86_64\bin" & @CRLF, $SEND_RAW) $sOutput = Send("gst-launch-1.0 videotestsrc ! autovideosink" & @CRLF, $SEND_RAW) Sleep(3000) ControlSend($hCmd, "", "", "exit" & @CR) EndIf ;$hCmd NOT "0"... I don't really know if this is the best way to open the console and send commands into it.  I'm also not sure about how to best catch any errors that may occur...likely this needs to be accomplished with the STDOUTREAD command however I've not had experience using it before and therefore would appreciate some advice that anybody may offer. 
      Basically I'm seeking guidance on how to best automate the opening of the console, sending lines of commands to be executed, and handling any potential errors in the execution of those commands...I thank you in advance.  Regards.
    • By MadhaN
      Hi all,
      I have a csv file as below, I wand to find srno from csv and send corresponding ip and pass to commend cmd prompt. 
      Please guide me to create script .
      srno,name,ip,pass
      1,name1,ip1,pass1
      2,name2,ip2,pass2
       
       
       
       
×
×
  • Create New...