Jump to content

Run() just broke...


Recommended Posts

I have been using a script for a long time with code resembling the following

FileMove(@ScriptFullPath, @ScriptDir & "\" & $NewName & ".exe")
Run(@ScriptDir & "\" & $NewName & ".exe")
FileMove(@ScriptDir & "\" & $NewName & ".exe", @ScriptFullPath)

Was working great, until one system startup I get some errors I flipped through quickly that I believe were DLL inconsistencies, which unfortunately I did not write down, but from vague remembrance of the name appeared to relate to autoit (one of the two was something similar to autoittray?) Anways, I am now getting an

Error: Unable to execute the external program

on the run call- In all cases, something brand new. Even calls to Run(@ScriptFullPath) no longer run correctly, as the script won't execute again.

Please help me... I overwrote all the autoit beta files (beta is all I use now anyway) with no avail. Could it be something to do with running process privileges and maybe a new virus on the computer?

Running itself repeatedly was an essential piece of scipt, and I really need help on this issue. Thanks for any help I can get.

Edited by Jlack0700
Link to comment
Share on other sites

Consider me eagerly frustrated. To see a script work fine one day and then a vital piece break the next is, well, you can guess...

$NewName = Random(1, 100, 1)
FileMove(@ScriptFullPath, @ScriptDir & "\" & $NewName & ".exe")
Run(@ScriptDir & "\" & $NewName & ".exe")
FileMove(@ScriptDir & "\" & $NewName & ".exe", @ScriptFullPath)

That is all the code needed to produce the error. As you can see, nothing else in the script has any effect on a run error this portion so it is not another piece of the script.

Link to comment
Share on other sites

Consider me eagerly frustrated. To see a script work fine one day and then a vital piece break the next is, well, you can guess...

$NewName = Random(1, 100, 1)
FileMove(@ScriptFullPath, @ScriptDir & "\" & $NewName & ".exe")
Run(@ScriptDir & "\" & $NewName & ".exe")
FileMove(@ScriptDir & "\" & $NewName & ".exe", @ScriptFullPath)

That is all the code needed to produce the error. As you can see, nothing else in the script has any effect on a run error this portion so it is not another piece of the script.

I don't see how that ever did work. You seem to be trying to move an executable while it's open and running. For clarity's sake I variablized your NewName:

; Create randomized file name
$NewName = Random(1, 100, 1)
$NewName = @ScriptDir & "\" & $NewName & ".exe"

; Move the currently running executable to the new file name, while it's running?!
FileMove(@ScriptFullPath, $NewName)

; Run script from new filename
Run($NewName)

; Move it back again, while the new filename is running and writing to the currently running script file?!
FileMove($NewName, @ScriptFullPath)

You should probably be able to copy an executable file while it being run, but I doubt you could ever move it or write to it while it was running... :whistle:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

If you don't believe that you can rename a running process, compile this script and run it. It works as expected on Windows XP, and the correct expectation is that the executable will be renamed while it is running.

If Not @Compiled Then Exit MsgBox(4096, "", "This script must be compiled to work")
FileMove(@ScriptFullPath, @ScriptDir & "\NewName.exe")
MsgBox(4096, "", "")
Link to comment
Share on other sites

Thats not technically the same thing as renaming a running executable. Windows sees that as overwriting a running executable. Renaming it something different during the overwrite is what makes it work. The basic test is to put an executable on your desktop, run it, and try to rename it while it's running. It can't be done while the file is being used by windows.

Pink Floyd - The Wall
Link to comment
Share on other sites

Alright, I found what broke and fortunately its not a huge hassle. By the way, I am using the most recent beta (1.32 (?) if I remember correctly).

My version of Run() won't process the parameter unless its surrounded by quotation marks. Like I said, this is brand new and I had been debugging the script for a long time before this occured.

Now, as a result, my runs need to look like-

Run('"'&$newName&'"')

in order to function correctly. If anyone would have an explanation for why this occured, I would be happy to hear from them out of sheer curiosity.

Link to comment
Share on other sites

Thats not technically the same thing as renaming a running executable. Windows sees that as overwriting a running executable. Renaming it something different during the overwrite is what makes it work. The basic test is to put an executable on your desktop, run it, and try to rename it while it's running. It can't be done while the file is being used by windows.

You don't think so, huh? Then try this more elaborate script which does the following:
  • On startup, if it's named Test1.exe, it renames itself to Test2.exe.
  • It runs Test2.exe.
  • Test2.exe is started.
  • Test2.exe copies itself to the name Test1.exe.
What we have here is a script renaming itself on the fly, something you claim can't be done. After renaming it, the new copy is launched which copies itself back over top of the original filename proving that Windows can handle file's being renamed without issue.

Does Windows have a lock on those files? Sure. Does Windows care what the name of the file is? Absolutely not. You can't delete the file or move it out of the diretory it's in, but you can definitely rename the file while it's running. This is a common trick used by installers to update DLLs in use. The installer renames the running DLL to something else, installs the new DLL in it's place, sets up to have the old DLL with it's new name deleted on next reboot and then asks the user if they want to reboot. Magically the new DLL is loaded upon reboot.

Edit: Oops, forgot to post the script. Also, one last thing. You probably won't see the rename occur. You'll likely just see two files in the directory when you are done running it. If you want to see the first script actually get renamed, insert a MsgBox() before Run() and wait until the Test1.exe becomes Test2.exe and dismiss the message box. Then watch as Test2.exe is run and copied back to Test1.exe.

Edit2: As a matter of fact, I've gone ahead and inserted the MsgBox() just to prove I'm not doing anything sneaky to fool you into thing my code works. Everything I'm doing is perfectly legal in Windows.

If Not @Compiled Then Exit MsgBox(4096, "", "This script must be compiled to work")

Local $sTest1 = @ScriptDir & "\Test1.exe"
Local $sTest2 = @ScriptDir & "\Test2.exe"

If @ScriptName = "Test1.exe" Then
    FileMove(@ScriptFullPath, $sTest2)
    While Not FileExists($sTest2)
        Sleep(10)
    WEnd
    MsgBox(4096, "", "Dismiss this after you see Test2.exe appear, Explorer can be slow")
    Run($sTest2)
    MsgBox(4096, "", "Test1")
ElseIf @ScriptName = "Test2.exe" Then
   ; Let's copy it back over top of Test.exe so that we leave both copies behind
    FileCopy(@ScriptFullPath, $sTest1)
    MsgBox(4096, "", "Test2")
Else
    MsgBox(4096, "", "Please name this script Test1.exe")
EndIf
Edited by Valik
Link to comment
Share on other sites

I do believe the next command isn't executed until the filemove is fully completed, though I could be wrong.

While Not FileExists($sTest2)
        Sleep(10)
    WEnd
Right. That code is more or less validation that FileMove() succeeded. It was also an attempt to get execution to stop until Test2.exe would appear in the directory but I've subsequently determined that the file does exist and that Explorer is just slow about displaying the rename.
Link to comment
Share on other sites

If you don't believe that you can rename a running process, compile this script and run it. It works as expected on Windows XP, and the correct expectation is that the executable will be renamed while it is running.

If Not @Compiled Then Exit MsgBox(4096, "", "This script must be compiled to work")
FileMove(@ScriptFullPath, @ScriptDir & "\NewName.exe")
MsgBox(4096, "", "")
Hmm... :)

First off, cool move with the Exit and MsgBox() on the same line! I didn't know that worked and it's not in the help file under Exit(). :)

I think I see how it works: The Exit function will return an exit code, and it can get the exit code from running other functions, so Exit is running MsgBox to generate the return code parameter.

I got to an XP box and tested it this way:

; Test_1.exe
; Test move while running

; Must be compiled to run
If Not @Compiled Then Exit MsgBox(64, "Test", "This script must be compiled to work")

; Create randomized file name
$NewName = Random(1, 100, 1)
$NewName = @ScriptDir & "\" & $NewName & ".exe"

If $CmdLine[0] > 0 And StringInStr($CmdLine[1], "-Rerun") Then
    MsgBox(64, "Test-2", "Rerun instance is running.")
Else
    ; Move the currently running executable to the new file name, while it's running?!
    If FileMove(@ScriptFullPath, $NewName) Then
        MsgBox(64, "Test-1", "Moved " & @ScriptFullPath & " to " & $NewName)
    Else
        MsgBox(16, "Test-1", "Failed to move " & @ScriptFullPath & " to " & $NewName)
    EndIf
    
    ; Run script from new filename
    Run($NewName & " -Rerun")
    
    ; Move it back again, while the new filename is running and writing to the currently running script file?!
    If FileMove($NewName, @ScriptFullPath) Then
        MsgBox(64, "Test-1", "Moved " & $NewName & " to " & @ScriptFullPath)
    Else
        MsgBox(16, "Test-1", "Failed to move " & $NewName & " to " & @ScriptFullPath)
    EndIf
EndIfoÝ÷ Ø]ا}§-Þ¶«ºyâ±yË­i¹^¶azw°~)^©jw[iɨ§Â+a¢ëfË"y«SänX§yö¢ç[yÆ®±è­v'gßÛlyëayì^rëZnW¢Ø^ì%¡Æ­Ö)^¶²hƶ§ÊZºÇ!È^rG¶¢W^­©Ý¶«zv¦y×âì²Ø^­æî¶+p¢é]m®éâ´µ©ÀºÚMê뢺®¢Õ'i¹^¶)z{azÇ+_WªºG£¯z¸!ÈZ­+%wºÚ"µÍNÈ[ØÜÛH]È[[[YBNÈ[  ÌÍÓ]Ó[YH    [È ][ÝÈT[][ÝÊBT[ØÜ   [È ][ÝÉÌLÕÝÌ^I][ÝÊoÝ÷ Ø Ýi×mërݱÊâ¦Ö®¶­sc²FW7Eó"æWP£²6ö×ÆVBGVÖ×67&@¤×6t&÷cBÂgV÷C´GVÖ×gV÷C²ÂgV÷C´GVÖ×67&B'VææærâââgV÷C²

Then it all works perfectly. It won't open a second instance of itself from the re-named location, but can run other scripts. :whistle:

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Insert a sleep statement between Run() and FileMove(). What is happening is that you are launching the second instance but moving the file away before AutoIt can open the executable and read the script. You are successfully running the second instance, but then when it starts up, we (as in AutoIt) tries to open the file up and read from it, which fails because FileMove() has renamed the file. Ergo, the second instance crashes because it can't read the script. This will fix the problem:

; Run script from new filename
    Run('"' & $NewName & '"' & " -Rerun")
    Sleep(1000)
  ; Move it back again, while the new filename is running and writing to the currently running script file?!
Link to comment
Share on other sites

Insert a sleep statement between Run() and FileMove(). What is happening is that you are launching the second instance but moving the file away before AutoIt can open the executable and read the script. You are successfully running the second instance, but then when it starts up, we (as in AutoIt) tries to open the file up and read from it, which fails because FileMove() has renamed the file. Ergo, the second instance crashes because it can't read the script. This will fix the problem:

; Run script from new filename
    Run('"' & $NewName & '"' & " -Rerun")
    Sleep(1000)
 ; Move it back again, while the new filename is running and writing to the currently running script file?!
Yep, just adding the Sleep() fixed it. Runs perfectly like this:

; Test_1.au3
; Test move while running

; Must be compiled to run
If Not @Compiled Then Exit MsgBox(64, "Test", "This script must be compiled to work")

; Create randomized file name
$NewName = Random(1, 100, 1)
$NewName = @ScriptDir & "\" & $NewName & ".exe"

If $CmdLine[0] > 0 And StringInStr($CmdLine[1], "-Rerun") Then
    MsgBox(64, "Test-2", "Rerun instance is running.")
Else
    ; Move the currently running executable to the new file name, while it's running?!
    If FileMove(@ScriptFullPath, $NewName) Then
        MsgBox(64, "Test-1", "Moved " & @ScriptFullPath & " to " & $NewName)
    Else
        MsgBox(16, "Test-1", "Failed to move " & @ScriptFullPath & " to " & $NewName)
    EndIf
    
    ; Run script from new filename
    Run($NewName & " -Rerun")
    Sleep(1000)
    
    ; Move it back again, while the new filename is running and writing to the currently running script file?!
    If FileMove($NewName, @ScriptFullPath) Then
        MsgBox(64, "Test-1", "Moved " & $NewName & " to " & @ScriptFullPath)
    Else
        MsgBox(16, "Test-1", "Failed to move " & $NewName & " to " & @ScriptFullPath)
    EndIf
EndIf

Now go to bed! Do you have any idea what time it... oh wait... I'm going to bed. Good night and thanks for the lessons learned! :whistle:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
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...