dJRa Posted August 12, 2007 Share Posted August 12, 2007 Hello! In a script (with Opt("GUIOnEventMode", 1)) I start an external program inside a "for $i" loop. I use ShellExecuteWait for not to start many instancies of the external program at the same time, but to have them start one after the other. My problem is, if I do it that way, the Gui doesn't react on events, as the script is paused while the external program is running. So I dont't have the control over my script, once the loop with ShellExecuteWait is started. How can I let the external program start one after the other, without loosing control over the script? Link to comment Share on other sites More sharing options...
enaiman Posted August 12, 2007 Share Posted August 12, 2007 ShellExecuteWait --------------------------------------------------------------------------------Runs an external program using the ShellExecute API and pauses script execution until it finishes.ShellExecute --------------------------------------------------------------------------------Runs an external program using the ShellExecute API.Good ol' help SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script wannabe "Unbeatable" Tic-Tac-Toe Paper-Scissor-Rock ... try to beat it anyway :) Link to comment Share on other sites More sharing options...
dJRa Posted August 13, 2007 Author Share Posted August 13, 2007 I know. But if I use SchellExecute, many instancies of the program run at the same time, because the loop goes on (as I already said). And that is exactly, what I do not want. I'm looking for a way of starting only one instancy at the same time without the script loosing the ability to react on pressed buttons (-->events). Link to comment Share on other sites More sharing options...
Richard Robertson Posted August 13, 2007 Share Posted August 13, 2007 So check for the process yourself and watch for it to end before you move on to the next one. Link to comment Share on other sites More sharing options...
Rick-O-Shea Posted August 13, 2007 Share Posted August 13, 2007 The launched process should be under running processes in windows --> check using: ProcessList ( ["name"] ) If so you can use ProcessExists ( "process" ) to poll if it's still running before launching the next instance. More info on these functions is in the help file incl. examples on how to use them. Grtz, Rick Link to comment Share on other sites More sharing options...
dJRa Posted August 13, 2007 Author Share Posted August 13, 2007 (edited) That's what I already tried: but if I do a loop like this one For $i = 0 to $Filecount ShellExecute("process.exe",$command[$i]) While ProcessExists("process.exe") Sleep(100) WEnd Next it has exactly the same effect as "ShellExecuteWait": while the processes don't run at the same time, my GUI again doesn't react on events. I have no idea what to do. How can I have the GUI react on events in such a while-wend loop? With "Opt("GUIOnEventMode", 1) " it works in the other parts of the script, but not in this one. EDIT: It also doesn't change anything, if I have my loop without the "Sleep(100)"-command. Edited August 13, 2007 by dJRa Link to comment Share on other sites More sharing options...
jefhal Posted August 13, 2007 Share Posted August 13, 2007 What if you launch your AutoIT script and the loop code from a batch file? You could even launch the AutoIT gui code and the loop code from another AutoIT program. That would make them independent, wouldn't it?I have no idea what to do. ...by the way, it's pronounced: "JIF"... Bob Berry --- inventor of the GIF format Link to comment Share on other sites More sharing options...
dJRa Posted August 13, 2007 Author Share Posted August 13, 2007 I didn't try it, but I suppose, that produces exactly the same problem. Link to comment Share on other sites More sharing options...
Reaper HGN Posted August 13, 2007 Share Posted August 13, 2007 If you post your code, we can see exactly what you are doing. This may help to provide a solution. Link to comment Share on other sites More sharing options...
dJRa Posted August 13, 2007 Author Share Posted August 13, 2007 Here it is. Simple script and not yet finished, don't laugh at it. :"> As you see, it is a simple GUI for lame. I know there are many of them on the net, but I want to do my own. expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> Global $DefaultStatus = "Ready..." Global $gaDropFiles[1] Global Const $WM_DROPFILES = 0x233 Opt("GUIOnEventMode", 1) $MainWindow = GUICreate("Script",600,500,-1,-1,-1,$WS_EX_ACCEPTFILES) $FileMenu = GUICtrlCreateMenu ("&File") $FileItem = GUICtrlCreateMenuItem ("Add File",$FileMenu) $RemoveItem = GUICtrlCreateMenuItem ("Remove File",$FileMenu) $Separator1 = GUICtrlCreateMenuItem ("",$FileMenu) $ExitItem = GUICtrlCreateMenuItem ("End",$FileMenu) $RecentFilesMenu = GUICtrlCreateMenu ("Recent Files",$FileMenu,1) $ViewMenu = GUICtrlCreateMenu("View") $ViewStatusItem = GUICtrlCreateMenuItem ("Statusbar",$ViewMenu) GUICtrlSetState(-1,$GUI_CHECKED) $HelpMenu = GUICtrlCreateMenu ("?") $InfoItem = GUICtrlCreateMenuItem ("Info",$HelpMenu) $OKButton = GUICtrlCreateButton ("OK",100,440,70,20) GUICtrlSetState(-1,$GUI_FOCUS) $CancelButton = GUICtrlCreateButton ("Cancel",230,440,70,20) $StatusLabel = GUICtrlCreateLabel ($defaultstatus,0,465,600,16,BitOr($SS_SIMPLE,$SS_SUNKEN)) $ListView = GUICtrlCreateListView ("Filename|Status", 1, 1, 600, 350) _GUICtrlListViewSetColumnWidth ( -1, 0, 500) _GUICtrlListViewSetColumnWidth ( -1, 1, 96) GuiCtrlSetState(-1,$GUI_DROPACCEPTED) GUICtrlCreateLabel ("LAME-Parameter:", 1, 383) $Par1 = GUICtrlCreateInput("-V2",88,380,513,20) GUICtrlSetOnEvent($FileItem, "FileItem") GUICtrlSetOnEvent($ViewStatusItem, "ViewStatusItem") GUICtrlSetOnEvent($InfoItem, "InfoItem") GUICtrlSetOnEvent($OKButton, "RunLame") GUICtrlSetOnEvent($CancelButton, "CancelButton") GUICtrlSetOnEvent($ExitItem, "CancelButton") GUISetOnEvent($GUI_EVENT_CLOSE, "CancelButton") GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES_FUNC") GUISetState() While 1 Sleep(100) WEnd Func FileItem() $File = FileOpenDialog("Dateien auswählen...",@ScriptDir,"Wave (*.wav)",4) If @error <> 1 Then GUICtrlCreateMenuitem ($File,$RecentFilesMenu) GuiCtrlCreateListViewItem($File,$ListView) EndIf EndFunc Func ViewStatusItem() If BitAnd(GUICtrlRead($viewstatusitem),$GUI_CHECKED) = $GUI_CHECKED Then GUICtrlSetState($viewstatusitem,$GUI_UNCHECKED) GUICtrlSetState($statuslabel,$GUI_HIDE) Else GUICtrlSetState($viewstatusitem,$GUI_CHECKED) GUICtrlSetState($statuslabel,$GUI_SHOW) EndIf EndFunc Func InfoItem() Msgbox(0,"Info","Script") EndFunc Func CancelButton() Exit EndFunc Func WM_DROPFILES_FUNC($hWnd, $msgID, $wParam, $lParam) Local $nSize, $pFileName Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255) For $i = 0 To $nAmt[0] - 1 $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0) $nSize = $nSize[0] + 1 $pFileName = DllStructCreate("char[" & $nSize & "]") DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", DllStructGetPtr($pFileName), "int", $nSize) ReDim $gaDropFiles[$i + 1] $gaDropFiles[$i] = DllStructGetData($pFileName, 1) If StringRight ($gaDropFiles[$i],4)=".wav" Then GuiCtrlCreateListViewItem($gaDropFiles[$i],$ListView) EndIf $pFileName = 0 Next EndFunc Func RunLame() $Par2 = GUICtrlRead($Par1) $Filecount=_GUICtrlListViewGetItemCount($ListView)-1 For $i = 0 to $Filecount $Par3 = _GUICtrlListViewGetItemText($ListView,$i,0) $command = $Par2&" """&$Par3&""" """&StringLeft($Par3,StringLen($Par3)-3)&"mp3""" ShellExecute("lame.exe",$command) While ProcessExists("lame.exe") WEnd Next EndFunc My problem is in the Function "RunLame". Within the While-Wend-Loop or with ShellExecuteWait, I can't cancel the script by pressing "Cancel" or a click on the "X" in the upper right angle. Link to comment Share on other sites More sharing options...
Reaper HGN Posted August 13, 2007 Share Posted August 13, 2007 Here it is. Simple script and not yet finished, don't laugh at it. :"> As you see, it is a simple GUI for lame. I know there are many of them on the net, but I want to do my own. expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> Global $DefaultStatus = "Ready..." Global $gaDropFiles[1] Global Const $WM_DROPFILES = 0x233 Opt("GUIOnEventMode", 1) $MainWindow = GUICreate("Script",600,500,-1,-1,-1,$WS_EX_ACCEPTFILES) $FileMenu = GUICtrlCreateMenu ("&File") $FileItem = GUICtrlCreateMenuItem ("Add File",$FileMenu) $RemoveItem = GUICtrlCreateMenuItem ("Remove File",$FileMenu) $Separator1 = GUICtrlCreateMenuItem ("",$FileMenu) $ExitItem = GUICtrlCreateMenuItem ("End",$FileMenu) $RecentFilesMenu = GUICtrlCreateMenu ("Recent Files",$FileMenu,1) $ViewMenu = GUICtrlCreateMenu("View") $ViewStatusItem = GUICtrlCreateMenuItem ("Statusbar",$ViewMenu) GUICtrlSetState(-1,$GUI_CHECKED) $HelpMenu = GUICtrlCreateMenu ("?") $InfoItem = GUICtrlCreateMenuItem ("Info",$HelpMenu) $OKButton = GUICtrlCreateButton ("OK",100,440,70,20) GUICtrlSetState(-1,$GUI_FOCUS) $CancelButton = GUICtrlCreateButton ("Cancel",230,440,70,20) $StatusLabel = GUICtrlCreateLabel ($defaultstatus,0,465,600,16,BitOr($SS_SIMPLE,$SS_SUNKEN)) $ListView = GUICtrlCreateListView ("Filename|Status", 1, 1, 600, 350) _GUICtrlListViewSetColumnWidth ( -1, 0, 500) _GUICtrlListViewSetColumnWidth ( -1, 1, 96) GuiCtrlSetState(-1,$GUI_DROPACCEPTED) GUICtrlCreateLabel ("LAME-Parameter:", 1, 383) $Par1 = GUICtrlCreateInput("-V2",88,380,513,20) GUICtrlSetOnEvent($FileItem, "FileItem") GUICtrlSetOnEvent($ViewStatusItem, "ViewStatusItem") GUICtrlSetOnEvent($InfoItem, "InfoItem") GUICtrlSetOnEvent($OKButton, "RunLame") GUICtrlSetOnEvent($CancelButton, "CancelButton") GUICtrlSetOnEvent($ExitItem, "CancelButton") GUISetOnEvent($GUI_EVENT_CLOSE, "CancelButton") GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES_FUNC") GUISetState() While 1 Sleep(100) WEnd Func FileItem() $File = FileOpenDialog("Dateien auswählen...",@ScriptDir,"Wave (*.wav)",4) If @error <> 1 Then GUICtrlCreateMenuitem ($File,$RecentFilesMenu) GuiCtrlCreateListViewItem($File,$ListView) EndIf EndFunc Func ViewStatusItem() If BitAnd(GUICtrlRead($viewstatusitem),$GUI_CHECKED) = $GUI_CHECKED Then GUICtrlSetState($viewstatusitem,$GUI_UNCHECKED) GUICtrlSetState($statuslabel,$GUI_HIDE) Else GUICtrlSetState($viewstatusitem,$GUI_CHECKED) GUICtrlSetState($statuslabel,$GUI_SHOW) EndIf EndFunc Func InfoItem() Msgbox(0,"Info","Script") EndFunc Func CancelButton() Exit EndFunc Func WM_DROPFILES_FUNC($hWnd, $msgID, $wParam, $lParam) Local $nSize, $pFileName Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255) For $i = 0 To $nAmt[0] - 1 $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0) $nSize = $nSize[0] + 1 $pFileName = DllStructCreate("char[" & $nSize & "]") DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", DllStructGetPtr($pFileName), "int", $nSize) ReDim $gaDropFiles[$i + 1] $gaDropFiles[$i] = DllStructGetData($pFileName, 1) If StringRight ($gaDropFiles[$i],4)=".wav" Then GuiCtrlCreateListViewItem($gaDropFiles[$i],$ListView) EndIf $pFileName = 0 Next EndFunc Func RunLame() $Par2 = GUICtrlRead($Par1) $Filecount=_GUICtrlListViewGetItemCount($ListView)-1 For $i = 0 to $Filecount $Par3 = _GUICtrlListViewGetItemText($ListView,$i,0) $command = $Par2&" """&$Par3&""" """&StringLeft($Par3,StringLen($Par3)-3)&"mp3""" ShellExecute("lame.exe",$command) While ProcessExists("lame.exe") WEnd Next EndFunc My problem is in the Function "RunLame". Within the While-Wend-Loop or with ShellExecuteWait, I can't cancel the script by pressing "Cancel" or a click on the "X" in the upper right angle. I cant really test as I am at work right now. However, what about running a cmd shell outside of your for loop, then sending commands to the window within your loop? I dont use lame myself, so not sure thats appropriate, but your code (even if it could wait between commands) would always create a new "instance" of a shell. Link to comment Share on other sites More sharing options...
dJRa Posted August 13, 2007 Author Share Posted August 13, 2007 I'm not sure I understood you right. In a CMD-Shell, I also can't send all of my commands "at once" (and that will happen if I do it out of the for-loop). Before sending a new command, I would always have to check (within the for-loop), if the command I sent before, is already finished. And for that, again I would need a While-Wend-loop. So it would be exactly the same. Or is it not, what you mean? Link to comment Share on other sites More sharing options...
Reaper HGN Posted August 13, 2007 Share Posted August 13, 2007 I'm not sure I understood you right.In a CMD-Shell, I also can't send all of my commands "at once" (and that will happen if I do it out of the for-loop).Before sending a new command, I would always have to check (within the for-loop), if the command I sent before, is already finished. And for that, again I would need a While-Wend-loop. So it would be exactly the same.Or is it not, what you mean?Yeah, you still will need a while loop. I think you understand what I was writing. Perhaps it isnt entirely appropriate with Lame. Ill have to try it on a system at home to see exactly what the behavior is. To be clear, though, you are saying you get several instances of the program, rather than one that takes all the commands, correct? So the desired outcome would be for the function to feed as string of commands to the shell (Lame.exe)? Link to comment Share on other sites More sharing options...
dJRa Posted August 13, 2007 Author Share Posted August 13, 2007 With the While-Wend-loop, the programs start one after the other, but I can't cancel the script, as GUIOnEventMode doesn't seem to work. Without the While-Wend-loop, theoretically I can cancel the script, but the instancies of lame all start at approximately the same time. So if I cancel the script, it is too late, as then, a large part of the for-loop has already passed. Even if I would manage to feed all commands in one string to the shell (which wouldn't work with lame, I suppose), it is not what I desire, as in that case, I also wouldn't have a possibility to stop the script, before all the commands are finished. Of course, I could close the shell and all processes would stop, but then I wouldn't new, which files are already converted and which not. I'm sure, there is a possibility, to react on GUI-events even withhin the While-Wend-loop. I just couldn't find the trick yet. Link to comment Share on other sites More sharing options...
Rick-O-Shea Posted August 15, 2007 Share Posted August 15, 2007 Did you think of changing your approach... Have a function pass the file name / Lame commands to some other function that handles one Lame-session at the time. Anyways - just a thought. Link to comment Share on other sites More sharing options...
PsaltyDS Posted August 15, 2007 Share Posted August 15, 2007 Here's an example of a GUI in Event Mode, that remains responsive to controls while running a sequence of processes: #include <GuiConstants.au3> Opt("GuiOnEventMode", 1) Global $iCnt = 3, $PID = "", $iTimer GUICreate("Test", 300, 200) GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit") $Label_1 = GUICtrlCreateLabel("Creating " & $iCnt & " more instances of Notepad...", 10, 10, 280, 20) GUICtrlCreateButton("Time", 10, 65, 100, 100) GUICtrlSetOnEvent(-1, "_Time") GUISetState() While 1 If Not ProcessExists($PID) Then If $iCnt = 0 Then Exit $PID = Run("notepad.exe") $iTimer = TimerInit() $iCnt -= 1 GUICtrlSetData($Label_1, "Creating " & $iCnt & " more instances of Notepad...") EndIf Sleep(20) WEnd Func _Quit() ProcessClose($PID) Exit EndFunc Func _Time() If ProcessExists($PID) Then MsgBox(64, "Time", "Current window has been up for " & _ Round(TimerDiff($iTimer) / 1000, 2) & " seconds.", 2) EndFunc Hope that helps... 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now