lod3n Posted June 28, 2007 Share Posted June 28, 2007 (edited) Sometimes, you just want to be able to run arbitrary commands, without worrying about which function you use to execute them.Try Run("http://www.google.com"). Sorry, you have to use ShellExecute for that.Try ShellExecute("winword c:\windows\win.ini"). Sorry, you have to use Run for that.Bah! Windows lets you run either of these in the Run dialog, found under the Start Menu. So why can't we? It appears that Windows accomplishes this by cheating: It actually tries both methods! [Correction: No it doesn't!] So, that's easy enough...expandcollapse popup; Example usages: $cmd = "this will not work" $result = _StartRun($cmd) If $result <> 1 Then MsgBox(16,"_StartRun Error:",$cmd & @CRLF & @CRLF & $result) $cmd = "http://www.google.com" $result = _StartRun($cmd) If $result <> 1 Then MsgBox(16,"_StartRun Error:",$cmd & @CRLF & @CRLF & $result) $cmd = "notepad c:\windows\win.ini" $result = _StartRun($cmd) If $result <> 1 Then MsgBox(16,"_StartRun Error:",$cmd & @CRLF & @CRLF & $result) ; #FUNCTION _StartRun # ======================================== ; Description ...: Tries to execute command with Run, and then ShellExec. Not the same as Start/Run, but similar effect ; Parameters ....: $sCmd - The command string to execute with parameters, as you might type into the real Start/Run ; $sFolder - The default folder to run in, defaults to @DesktopDir to match the real Start/Run ; $rState - The application visiblity flag, defaults to @SW_SHOWNORMAL - not sure if Start/Run does the same ; Return values .: Success - Bool, 1 = success, 0 = failure ; Author(s) .....: lod3n, SlimShady ; Remarks .......: ; Related .......: Run, ShellExec, and SlimShady's _ShellExec upon which this is partially based ; =============================================================== Func _StartRun($sCmd, $sFolder = @DesktopDir, $rState = @SW_SHOWNORMAL) Local $prevRunFatal = Opt("RunErrorsFatal", 0) ;1=fatal, 0=silent set @error Local $pid = Run($sCmd, $sFolder, $rState) If $pid = 0 Then ; AutoIt's built in ShellExecute abstracts this DllCall. Let's just call it directly. Not working in without MSLU installed Local $aRet = DllCall("shell32.dll", "long", "ShellExecute", _ "hwnd", 0, _ "string", "", _ ; would be the verb. it defaults to OPEN, or whatever verb is default for the file you specified "string", $sCmd, _ "string", "", _ ; would be a command argument, but we don't need this as we try Run first, above "string", $sFolder, _ "int", $rState) Local $errorText = _GetLastErrorMessage() If $aRet[0] > 32 Then Opt("RunErrorsFatal", $prevRunFatal) Return 1 ; ShellExecute Success! Else Opt("RunErrorsFatal", $prevRunFatal) Return $errorText ; Run failed, and so did ShellExecute EndIf Else Opt("RunErrorsFatal", $prevRunFatal) Return 1 ; Run Success! EndIf EndFunc ;==>_StartRun Func _GetLastErrorMessage() Local $ret, $s Local $p = DllStructCreate("char[4096]") Local Const $FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000 If @error Then Return "" $ret = DllCall("Kernel32.dll", "int", "GetLastError") $ret = DllCall("kernel32.dll", "int", "FormatMessage", _ "int", $FORMAT_MESSAGE_FROM_SYSTEM, _ "ptr", 0, _ "int", $ret[0], _ "int", 0, _ "ptr", DllStructGetPtr($p), _ "int", 4096, _ "ptr", 0) $s = DllStructGetData($p, 1) Return $s EndFunc ;==>_GetLastErrorMessageThis function should work with Windows 98 if MSLU (Microsoft Layer for Unicode) is installed:http://msdn2.microsoft.com/en-us/library/ms812865.aspx Edited June 28, 2007 by lod3n [font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font] Link to comment Share on other sites More sharing options...
Richard Robertson Posted June 28, 2007 Share Posted June 28, 2007 (edited) First of all, no, Windows does not try both. Microsoft has a parser to read the filename and determines whether it is registered as an executable or a data file. If it is an executable, a new process is started. If it is not an executable, the registry is checked to see if a new process should be started, or if a DDE message should be sent to an already existing process. Second, it's not bad as far as functions go. I can see this getting a lot of use. Edited June 28, 2007 by Mr Icekirby Link to comment Share on other sites More sharing options...
lod3n Posted June 28, 2007 Author Share Posted June 28, 2007 Mr Icekerby, I appreciate that information. My source was wrong it seems (thanks again, Internet!). I'd like to replicate that same process. Before coming up with this, I'd played around with writing my own parser, and was never happy with the limitations - it was hard to predict all of the possible usages. Do you know of a reference that I could look at to improve this? [font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font] Link to comment Share on other sites More sharing options...
Richard Robertson Posted June 28, 2007 Share Posted June 28, 2007 I remember an old environment variable that used to exist. It had to do with executable extensions. They were .exe, .pif, and .bat. I'm sure that no one uses pif files anymore. Batch files have to be executed through a command interpretter. Exe files are easy enough to the check the extension of. As for the registry configurations for the opening of data files, I don't quite understand it. I've looked at the entries in my registry to learn how they work, but I never had an official documentation. Link to comment Share on other sites More sharing options...
Jettison Posted June 28, 2007 Share Posted June 28, 2007 Perfect! Just what I needed. Thanks lod3n! [font="Impact"]Cats rule, humans drool.[/font] Link to comment Share on other sites More sharing options...
Jettison Posted June 28, 2007 Share Posted June 28, 2007 (edited) Hm..Apparently this doesn't work in 98... It opens programs but not paths. Edited June 28, 2007 by Jettison [font="Impact"]Cats rule, humans drool.[/font] Link to comment Share on other sites More sharing options...
lod3n Posted June 28, 2007 Author Share Posted June 28, 2007 I'm sorry, I don't have a floppy drive with which to install my copy of Windows 1998 in order to test and find a solution for you. Maybe this? Func _StartRun98($sCmd, $sFolder = @DesktopDir, $rState = @SW_SHOWNORMAL) Local $prevRunFatal = Opt("RunErrorsFatal", 0) ;1=fatal, 0=silent set @error Local $pid = Run($sCmd, $sFolder, $rState) Opt("RunErrorsFatal", $prevRunFatal) ; this is just so it plays nice with everybody else If $pid = 0 Then $RetVal = ShellExecute($sCmd,"",$sFolder,"",$rState) Return $RetVal ; ShellExecute Success! Else Return 1 ; Run Success! EndIf EndFunc ;==>_StartRun98 [font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font] Link to comment Share on other sites More sharing options...
Jettison Posted June 28, 2007 Share Posted June 28, 2007 I'll try it out. Actually I don't own 98, I was asking a friend of mine to test my script..and she said it only works with programs. Will set it up to detect OS and let you know. Thanks [font="Impact"]Cats rule, humans drool.[/font] Link to comment Share on other sites More sharing options...
Jettison Posted June 28, 2007 Share Posted June 28, 2007 In her own words: "that works, with paths" You're a lifesaver, lod3n. Thanks much. [font="Impact"]Cats rule, humans drool.[/font] Link to comment Share on other sites More sharing options...
lod3n Posted June 28, 2007 Author Share Posted June 28, 2007 _StartRun98 might actually be better than _StartRun then... [font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font] Link to comment Share on other sites More sharing options...
Jettison Posted June 28, 2007 Share Posted June 28, 2007 (edited) Oh I can just replace it? [Edit] Guess I can. Works like a charm. Could you add error messages too? Edited June 28, 2007 by Jettison [font="Impact"]Cats rule, humans drool.[/font] Link to comment Share on other sites More sharing options...
lod3n Posted June 28, 2007 Author Share Posted June 28, 2007 I've updated the original version. Please see the original post. [font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font] Link to comment Share on other sites More sharing options...
Uten Posted June 28, 2007 Share Posted June 28, 2007 (edited) I remember an old environment variable that used to exist. It had to do with executable extensions. They were .exe, .pif, and .bat. I'm sure that no one uses pif files anymore. Batch files have to be executed through a command interpretter. Exe files are easy enough to the check the extension of.As for the registry configurations for the opening of data files, I don't quite understand it. I've looked at the entries in my registry to learn how they work, but I never had an official documentation.Wonder if that was a result of parsing output from ftype and assoc in @comspec?Open a command shell and type help assoc, help ftype. Or just assoc && ftypeEDIT:Typo's Edited June 28, 2007 by Uten Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
lod3n Posted June 28, 2007 Author Share Posted June 28, 2007 assoc and fftype are simply looking up values in HKCR in the registry. There's been some work done with this kind of thing:http://www.autoitscript.com/forum/index.php?showtopic=47845The problem is making a flexible enough parser to handle all of the potential command someone might try and enter. It's about handling spaces, slashes and quotes well enough to find and execute the correct command, with the correct parameters, OR opening the correct file with the correct application, OR detecting the requested protocol (http://, ftp://, res://, etc.) and correctly opening the associated application. Any one of these items is simple enough on it's own, but to make something smart enough to tell what kind of random command you've specified and correctly executing it is tricky. [font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font] Link to comment Share on other sites More sharing options...
Jettison Posted June 28, 2007 Share Posted June 28, 2007 Marvellous. Tried it and works great. Thanks again, lod3n. [font="Impact"]Cats rule, humans drool.[/font] Link to comment Share on other sites More sharing options...
Jettison Posted June 28, 2007 Share Posted June 28, 2007 Ok erm...it does not work on windows 98 even with MSLU installed...no paths will open, only programs. [font="Impact"]Cats rule, humans drool.[/font] Link to comment Share on other sites More sharing options...
lod3n Posted June 29, 2007 Author Share Posted June 29, 2007 if @OSType = "WIN32_WINDOWS" then _StartRun98($cmd) else _StartRun($cmd) endif That may be as good as it gets. [font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font] Link to comment Share on other sites More sharing options...
Jettison Posted June 29, 2007 Share Posted June 29, 2007 Ok, then I'll switch back to using both StartRun and StartRun98. [font="Impact"]Cats rule, humans drool.[/font] Link to comment Share on other sites More sharing options...
bhoar Posted June 29, 2007 Share Posted June 29, 2007 Ok, then I'll switch back to using both StartRun and StartRun98.That check could still be integrated into a single UDF...-brendan Link to comment Share on other sites More sharing options...
Jettison Posted June 29, 2007 Share Posted June 29, 2007 Ehh I'm just using _StartRun98 renamed _StartRun only. Works both on my XP and my friend's 98, so I'll stick to it. [font="Impact"]Cats rule, humans drool.[/font] 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