ezzetabi Posted September 3, 2004 Author Posted September 3, 2004 Yeah, spaces. I hate them. I re check the code.
ezzetabi Posted September 3, 2004 Author Posted September 3, 2004 (edited) I hope this is bullet proof. It search for the executable also in the CLSID, keys if the FLTP does not give answers. Tested with Paint shop pro (it executable have space) with a filename with spaces... expandcollapse popupMsgBox(0, '', _ShellExecute('"wabmig.exe"', '', '')) Func _ShellExecute($LINE, $FOLDER, $VERB) ; -1 Badly formatted line ; -2 File not found Local $LINE, $I, $I2, $FILE, $ARGUMENTS, $FLTP = '', $EXT = '', $CMD, $PATH, $PATHEXT, $HANDLE, _ $DEFVERB, $ENV, $ENVX, $WILDCARDS = 0, $FOLDER, $CLSID $LINE = StringStripWS($LINE, 3) $LINE = _SplitArguments($LINE) If $line = -1 Then Return -1 $line = StringSplit($line,@lf) $FILE = $LINE[1] $ARGUMENTS = $LINE[2] $LINE = '' ;Now we separed $File and $Arguments If StringInStr($FILE, '*') Or StringInStr($FILE, '?') Then $WILDCARDS = 1 Select Case StringInStr(FileGetAttrib($FILE), 'd');It is a folder $FLTP = 'Folder' $LINE = '"' & $FILE & '" ' & $ARGUMENTS Case Not FileExists($FILE) ;It seems the file does not exist Select Case _Any(StringLeft($FILE, StringInStr($FILE, ':')), 'http:|https:');It is a internet address $EXT = 'html' $LINE = $FILE & ' ' & $ARGUMENTS Case StringLeft($FILE, 4) = 'www.';It is technically badly formatted internet address. $EXT = 'html' $LINE = $FILE & ' ' & $ARGUMENTS Case StringLeft($FILE, StringInStr($FILE, ':')) = 'mailto:';It is email link $FLTP = 'mailto' $LINE = $FILE & ' ' & $ARGUMENTS Case Not StringInStr($FILE, '\') And StringInStr($FILE, '.', 0, -1);It is a file name with extension, but it isn't in the current folder. Select Case RegRead('HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\' & $FILE, '') <> '';It have its HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths key $LINE = _RunRegShortCut($FILE, $ARGUMENTS) Case Else;We need to look for this file in the whole %path% $PATH = StringSplit(EnvGet('path'), ';') For $I = 1 To $PATH[0] $HANDLE = FileFindFirstFile($PATH[$I] & '\' & $FILE) If $HANDLE = -1 Then ContinueLoop $LINE = '"' & $PATH[$I] & '\' & FileFindNextFile($HANDLE) & '" ' & $ARGUMENTS FileClose($HANDLE) ExitLoop Next If $LINE = '' Then Return -2 EndSelect Case StringInStr($FILE, '\', 0, -1) < StringInStr($FILE, '.', 0, -1);It is full path with extension, but it does not exist. ;So we can assume that is badly typed. Return -2 Case StringInStr($FILE, '\', 0, -1) > StringInStr($FILE, '.', 0, -1);It is path without extension. The file still may exists. ;We have to check all %pathext% in the given folder $PATH = StringLeft($FILE, StringInStr($FILE, '\', 0, -1)) $FILE = StringTrimLeft($FILE, StringInStr($FILE, '\', 0, -1)) $PATHEXT = StringSplit(EnvGet('pathext'), ';') For $I = 1 To $PATHEXT[0] $HANDLE = FileFindFirstFile($PATH & $FILE & $PATHEXT[$I]) If $HANDLE = -1 Then ContinueLoop $LINE = '"' & $PATH & FileFindNextFile($HANDLE) & '" ' & $ARGUMENTS FileClose($HANDLE) ExitLoop Next If $LINE = '' Then Return -2 Case Not StringInStr($FILE, '\', 0, -1) And Not StringInStr($FILE, '.', 0, -1);It is just a word, with no extension and no path. Good hunt. ;We have to check all %pathext% in the HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths and in all %path% $PATHEXT = StringSplit(EnvGet('pathext'), ';') For $I = 1 To $PATHEXT[0] RegRead('HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\' & $FILE & $PATHEXT[$I], '') If @error Then ContinueLoop $FILE = $FILE & $PATHEXT[$I] $LINE = _RunRegShortCut($FILE, $ARGUMENTS) ExitLoop Next If $LINE = '' Then $PATH = StringSplit(EnvGet('path'), ';') For $I = 1 To $PATH[0] For $I2 = 1 To $PATHEXT[0] $HANDLE = FileFindFirstFile($PATH[$I] & '\' & $FILE & $PATHEXT[$I2]) If $HANDLE = -1 Then ContinueLoop $LINE = '"' & $PATH[$I] & '\' & FileFindNextFile($HANDLE) & '" ' & $ARGUMENTS ExitLoop 2 Next Next If $LINE = '' Then Return -2 EndIf Case Else;I do not know when it may happen, but... Return -1 EndSelect Case Else;The file clearly exists If $WILDCARDS = 0 Then $LINE = '"' & $FILE & '" ' & $ARGUMENTS Else $PATH = StringLeft($FILE, StringInStr($FILE, '\', 0, -1)) $HANDLE = FileFindFirstFile($FILE) $LINE = '"' & $PATH & FileFindNextFile($HANDLE) & '" ' & $ARGUMENTS FileClose($HANDLE) EndIf EndSelect $LINE = StringSplit(_SplitArguments($LINE), @LF) $FILE = FileGetShortName($LINE[1]);ok, it is not the best, but it a pain othewise. $ARGUMENTS = $LINE[2] If $EXT = '' Then $EXT = StringTrimLeft($FILE, StringInStr($FILE, ".", 0, -1)) If $EXT = 'lnk' Then;Beasts of .lnk files... $FLTP = FileGetShortcut($FILE) If FileExists($FLTP[0]) Then Run($FLTP[0] & ' ' & $FLTP[2] & $ARGUMENTS, $FLTP[1], $FLTP[6]) $CMD = $FILE & ' ' & $ARGUMENTS $FLTP = '' Else If $FLTP = '' Then $FLTP = RegRead("HKEY_CLASSES_ROOT\." & $EXT, "") If @error Then $FLTP = $EXT & "file" EndIf $DEFVERB = RegRead("HKEY_CLASSES_ROOT\" & $FLTP & "\shell", "") If $DEFVERB = "" Then $DEFVERB = "Open" If $VERB = "" Then $CMD = RegRead("HKEY_CLASSES_ROOT\" & $FLTP & "\shell\" & $DEFVERB & "\command", "") Else $CMD = RegRead("HKEY_CLASSES_ROOT\" & $FLTP & "\shell\" & $VERB & "\command", "") EndIf If @error Then $CMD = RegEnumKey("HKEY_CLASSES_ROOT\" & $FLTP & "\shell", 1) EndIf If @error Then $CLSID = RegRead("HKEY_CLASSES_ROOT\" & $FLTP & "\CLSID", '') If $CLSID = '' Then Return 2 Select Case RegRead("HKEY_CLASSES_ROOT\CLSID\" & $CLSID & '\LocalServer32', '') <> '' $CMD = RegRead("HKEY_CLASSES_ROOT\CLSID\" & $CLSID & '\LocalServer32', '') $cmd = $cmd & ' "' & $file & '" ' & $ARGUMENTS Case RegRead("HKEY_CLASSES_ROOT\CLSID\" & $CLSID & '\LocalServer', '') <> '' $CMD = RegRead("HKEY_CLASSES_ROOT\CLSID\" & $CLSID & '\LocalServer', '') $cmd = $cmd & ' ' & $file & ' ' & $ARGUMENTS Case Else Return -2 EndSelect Else $CMD = StringReplace($CMD, "%l", $FILE) $CMD = StringReplace($CMD, "%1", $FILE) $CMD = StringReplace($CMD, "%*", $ARGUMENTS) $CMD = StringReplace($CMD, "%2", $ARGUMENTS) For $I = 2 To 9 $CMD = StringReplace($CMD, "%" & $I, "") Next $ENV = StringInStr($CMD, "%", 0, 1) If Not @error Then For $I = 1 To 5 Step 2 If Not StringInStr($CMD, "%", 0, $I) Then ExitLoop $ENVX = StringMid($CMD, StringInStr($CMD, "%", 0, $I) + 1, StringInStr($CMD, "%", 0, $I + 1) - 2) $CMD = StringReplace($CMD, "%" & $ENVX & "%", EnvGet($ENVX)) Next EndIf If StringInStr($CMD, '/idlist,%I') Then $CMD = StringReplace($CMD, ',/idlist,%I', '');needed for opening folders with explorer. $CMD = StringReplace($CMD, '/idlist,%I', '') EndIf While StringInStr($CMD, '""') $CMD = StringReplace($CMD, '""', '') Wend EndIf Run($CMD, $FOLDER) If @error = 1 Then Return -2 EndIf Return $CMD EndFunc ;==>_ShellExecute Func _SplitArguments($LINE) Local $LINE, $FILE, $I, $ARGUMENTS If StringLeft($LINE, 1) = '"' Then;If the line begins with a " the text between the two " is $file and the other is $arguments. $I = StringInStr($LINE, '"', 0, 2) If $I = 0 Then Return -1 ;If there is not a second " the line is badly formatted $FILE = StringMid($LINE, 2, $I - 2) $ARGUMENTS = StringTrimLeft($LINE, $I) Else If StringInStr($LINE, ' ') Then;If there are no ", so is the first space that divide $file and $arg. $FILE = StringLeft($LINE, StringInStr($LINE, ' ') - 1) $ARGUMENTS = StringTrimLeft($LINE, StringInStr($LINE, ' ') - 1) Else ;If there are no " and no spaces, there are no arguments. $FILE = $LINE EndIf EndIf Return $FILE & @LF & $ARGUMENTS EndFunc ;==>_SplitArguments Func _RunRegShortCut($FILE, $ARGUMENTS) Local $FILE, $CMD, $ARGUMENTS $CMD = RegRead('HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\' & $FILE, '') If StringLeft($cmd,1) <> '"' And StringInStr($cmd,' ') And Not StringInStr($cmd,'%') Then $cmd = '"' & $cmd & '"' $CMD = StringReplace($CMD, '%SystemRoot%', @WindowsDir) $CMD = StringReplace($CMD, '%ProgramFiles%', @ProgramFilesDir) $CMD = _SplitArguments($CMD) Select Case StringInStr($CMD, '%*') $CMD = StringReplace($CMD, '%*', $ARGUMENTS) Case StringInStr($CMD, '%1') $CMD = StringReplace($CMD, '%1', $ARGUMENTS) Case StringInStr($CMD, '%l') $CMD = StringReplace($CMD, '%l', $ARGUMENTS) EndSelect While StringInStr($CMD, '%') $CMD = StringReplace($CMD, StringMid($CMD, StringInStr($CMD, '%'), 2), '') Wend $CMD = StringSplit($CMD, @LF) $CMD = '"' & $CMD[1] & '" ' & $CMD[2] Return $CMD EndFunc ;==>_RunRegShortCut Func _Any($ITEM, $LIST) Local $LIST $LIST = StringSplit($LIST, '|') For $C = 1 To $LIST[0] If $LIST[$C] = $ITEM Then Return 1 EndIf Next Return 0 EndFunc ;==>_Any Edited September 4, 2004 by ezzetabi
m0n5ter Posted September 3, 2004 Posted September 3, 2004 (edited) Still not happening. Still opens with the open/new/blank dialogue. When I type "filemaker pro.exe" at a command prompt it opens to a blank screen, with no dialogue. When I type "filemaker pro.exe" c:\file.fp5 it opens the file, so I assume it is possible. BTW the path to my file is C:\Documents and Settings\Monster\Desktop\Clones\file.fp5 Edited September 3, 2004 by m0n5ter
m0n5ter Posted September 3, 2004 Posted September 3, 2004 OK It has something to do with the path. When I do this: _ShellExecute('"C:\Documents and Settings\Monster\Desktop\Clones\dentists.fp5"','','') It works When I do this: _ShellExecute('dentists.fp5','','') It does not
this-is-me Posted September 3, 2004 Posted September 3, 2004 @m0n5ter, You have Norton Antivirus 2003 or better... Who else would I be?
m0n5ter Posted September 3, 2004 Posted September 3, 2004 @m0n5ter, You have Norton Antivirus 2003 or better... <{POST_SNAPBACK}>Yeah, why, is that the problem?
this-is-me Posted September 3, 2004 Posted September 3, 2004 No. I just noticed it. The file path "bug" you reported is not actually a "bug" per se. It is a windows limitation. Until windows searches every directory on your computer for a filename, Autoit will not do it either. Who else would I be?
m0n5ter Posted September 3, 2004 Posted September 3, 2004 No. I just noticed it. The file path "bug" you reported is not actually a "bug" per se. It is a windows limitation. Until windows searches every directory on your computer for a filename, Autoit will not do it either. <{POST_SNAPBACK}>How did you notice it? Was it from my screenshot?
this-is-me Posted September 4, 2004 Posted September 4, 2004 Yes. That gobbledygook in your screenshot is from NAV. Who else would I be?
ezzetabi Posted September 4, 2004 Author Posted September 4, 2004 (edited) No, this-is-me. If the problem were a path problem the udf should return -2, not start the program... There is somethig strange. Probably a Return -2 is missing somewhere. Edited September 4, 2004 by ezzetabi
ezzetabi Posted September 4, 2004 Author Posted September 4, 2004 ... I do not know. A string like dentist.fp5 should activate this part of code... Case Not StringInStr($FILE, '\') And StringInStr($FILE, '.', 0, -1);It is a file name with extension, but it isn't in the current folder. Select Case RegRead('HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\' & $FILE, '') <> '';It have its HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths key $LINE = _RunRegShortCut($FILE, $ARGUMENTS) Case Else;We need to look for this file in the whole %path% $PATH = StringSplit(EnvGet('path'), ';') For $I = 1 To $PATH[0] $HANDLE = FileFindFirstFile($PATH[$I] & '\' & $FILE) If $HANDLE = -1 Then ContinueLoop $LINE = '"' & $PATH[$I] & '\' & FileFindNextFile($HANDLE) & '" ' & $ARGUMENTS FileClose($HANDLE) ExitLoop Next If $LINE = '' Then Return -2 ...And of course finding nothing in the Registry should look for the file in the path, and since the file will be not found the $line should be still empty and activate the Return... m0n5ter, can you please put a msgbox(0,'',$line) just before If $line = '' Then Return -2 ? Is it empty, if it is not what is wrote?
ezzetabi Posted September 4, 2004 Author Posted September 4, 2004 I hope that this indeed solves something. When the script have the full path it converts it to its short version. So with no spaces there should be no problems... Those " are indeed a pain...
m0n5ter Posted September 5, 2004 Posted September 5, 2004 I hope that this indeed solves something. When the script have the full path it converts it to its short version. So with no spaces there should be no problems... Those " are indeed a pain... <{POST_SNAPBACK}>OK I figured it out, but have not solved it. Basically $line when it first gets into the UDF is correct. But when it passes $line to your UDF Func _SplitArguments($LINE) and passes the results back, $file did not equal what $line did. I fixed it for my solution by just making $file = $line since I am only using it in this one solution, with no arguments. For your information, $file on it's return was "C:\Documents" and $arguments was " and Settings\Monster\Desktop\Clones\Dentists.fp5" So it would appear as though Func _SplitArguments($LINE) is making a mess of the splint because of the presence of the space. But I didn't have time to check it out any further, but as I said I got it working for me by missing out the Func _SplitArguments($LINE) and making $file = $line. Cheers Monster
fabio Posted September 13, 2004 Posted September 13, 2004 Guys, I need some help. I need to use _ShellExecute to open IE and load a URL , but it doesn´t work on Windows NT. Can anyone help me? Thanks.
bshoenhair Posted September 15, 2004 Posted September 15, 2004 (edited) ezzetabi, Nice Job I let windows explorer do all the work. Note: needs improvements, but is good enough for me because it does exactly what I need. Opt("WinTitleMatchMode",4) Opt("TrayIconDebug",1) _LaunchSomeThing(@ProgramFilesDir & "\AutoIt3\AutoIt.chm") Func _LaunchSomeThing($Path) $PathArray = StringSplit($Path,"\") $FileName = $PathArray[$PathArray[0]] $Dir = StringTrimRight($Path,StringLen($PathArray[$PathArray[0]]) + 1) If StringRight($Dir,1) = "\" Then $Dir = StringTrimRight($Dir,1) Run("explorer " & $Dir,"",@SW_MINIMIZE) $ExpClass = "classname=CabinetWClass|classname=ExploreWClass" $ExpClassArray = StringSplit($ExpClass,"|") For $i = 1 To $ExpClassArray[0] While 1 If WinExists($ExpClassArray[$i]) Then ExitLoop(2) Sleep(10) Wend Next WinWait($ExpClassArray[$i],$Dir) $ExpHandle = WinGetHandle($ExpClassArray[$i],$Dir) ControlFocus($ExpClassArray[$i],$Dir,"SysListView321") ControlSend($ExpClassArray[$i],$Dir,"SysListView321",$Filename) ControlSend($ExpClassArray[$i],$Dir,"SysListView321","{ENTER}") WinClose($ExpHandle,$Path) EndFunc Edited September 15, 2004 by bshoenhair
SlimShady Posted January 28, 2005 Posted January 28, 2005 (edited) I improved ezzetabi's ShellExecute.It now works almost exactly like Run.No full path necessary and you can hide, minimize the application window.And ofcourse the purpose of this function: run non-executables.Code is available in this topic:http://www.autoitscript.com/forum/index.php?showtopic=5383--removed--- Edited January 28, 2005 by SlimShady
this-is-me Posted January 28, 2005 Posted January 28, 2005 Man! I must have started something. It's amazing that a simple idea made by one person (me) can be changed and improved by another (ezzetabi) and eventually updated and improved by yet another person (slimshady). This is something that has gone much farther than I ever expected. One thing I did notice Slim is that you cannot select a "verb" to execute on a file using the DllCall version. Therefore, one cannot (for example) launch the Print verb on a txt file or similar situations. Who else would I be?
SlimShady Posted January 28, 2005 Posted January 28, 2005 (edited) I made an alternative to the Run function.I was bored that's why I made it functional.Edit:I just read the thread completely and I realise that ezzetabi didn't even use ShellExecute.I used ezzetabi's function which he posted here. Edited January 28, 2005 by SlimShady
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