Что нового

Как обработать ошибку порожденную функцией ShellExecute ?

VladUs

Скриптер
Сообщения
621
Репутация
181
Если в функцию ShellExecute указать в качестве параметра не существующее имя файла, то возникает сообщение с ошибкой Windows: Windows не удалось найти файл с "таким-то" именем. При этом скрипт приостанавливает свою работу до тех пор пока не закрыть данное сообщение. Необходимо чтобы вместо (а не после) данной ошибки Windows появлялось сообщение об ошибке прописанной в коде скрипта. Или как вариант прописать в коде закрытие сообщения после его возникновения. К сожелению ControlSend в данном случае не помогает(даже не знаю почему. Пробывал из другого скрипта закрывать данное окно - не выходит).
Помогите, буду очень признателен.

Примерный код:

Код:
HotKeySet("{F1}", "_Start") 

while 1
Sleep(100)
wend

Func _Start()
$Box=InputBox("Введите программу", "Введите название программы")
ShellExecute($Box)
EndFunc
 
Автор
V

VladUs

Скриптер
Сообщения
621
Репутация
181
А почему не удается закрыть сообщение с ошибкой с помощью ControlSend ?


Добавлено:
Сообщение автоматически объединено:



Да, оно останавливает работу скрипта.
Почему другим скриптом не могу закрыть ?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
В библиотеке WinAPEx есть функция WinAPI_PathSearchAndQualify(), которая делает то, что нужно.

Код:
#Include <WinAPIEx.au3>

$Data = InputBox("Введите программу",  "Введите название программы")
$Path = _WinAPI_PathSearchAndQualify($Data, 1)
If Not $Path Then
	MsgBox(16, 'Ошибка', $Data & ' не найден.')
Else
	ShellExecute($Path)
EndIf
 
Автор
V

VladUs

Скриптер
Сообщения
621
Репутация
181
Спасибо Yashied.
Так и знал что без WinApi здесь не обойтись.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
А еще лучше использовать Run() вместо ShellExecute().
 
Автор
V

VladUs

Скриптер
Сообщения
621
Репутация
181
еще интересная функция _WinAPI_PathFindOnPath, как я понял, возвращает местоположение файла ища его во всем переменном окружении, без необходимости создания дополнительных файлов.

qsort твой код тоже мне нравится. Впрочем если ввести "www.mail.ru" , то ничего не выйдет. Поэтому использую ShellExecute()
И изначально тема звучит: как обойти ошибку ShellExecute()
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Можно ещё использовать самопальную функцию ShellExecuteEx:

Код:
_ShellExecuteEx($Box)

Func _ShellExecuteEx($sCmd, $sArgs = "", $sFolder = "", $sVerb = "", $iState = @SW_SHOWNORMAL, $hWnd = 0)
	Local $stINFO = DllStructCreate("long;long;long;ptr;ptr;ptr;ptr;long;long;long;ptr;long;long;long;long")
	Local $stVerb = DllStructCreate("char[15];char")
	Local $stPath = DllStructCreate("char[255];char")
	Local $stArgs = DllStructCreate("char[255];char")
	Local $stWDir = DllStructCreate("char[255];char")
	
	DllStructSetData($stVerb, 1, $sVerb)
	
	DllStructSetData($stPath, 1, $sCmd)
	DllStructSetData($stWDir, 1, $sFolder)
	DllStructSetData($stArgs, 1, $sArgs)
	
	DllStructSetData($stINFO, 1, DllStructGetSize($stINFO))
	DllStructSetData($stINFO, 2, BitOR(0xC, 0x40, 0x400))
	DllStructSetData($stINFO, 3, $hWnd)
	DllStructSetData($stINFO, 4, DllStructGetPtr($stVerb))
	DllStructSetData($stINFO, 5, DllStructGetPtr($stPath))
	DllStructSetData($stINFO, 6, DllStructGetPtr($stArgs))
	DllStructSetData($stINFO, 7, DllStructGetPtr($stWDir))
	DllStructSetData($stINFO, 8, $iState)
	
	Local $aRet = DllCall("Shell32.dll", "int", "ShellExecuteEx", "ptr", DllStructGetPtr($stINFO))
	
	If Not IsArray($aRet) Or Not $aRet[0] Then
		Return SetError(2, 0, 0)
	EndIf
	
	Return 1
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
CreatoR сказал(а):
Можно ещё использовать самопальную функцию ShellExecuteEx...

Почему самопальную? Это правильная функция, правильнее, чем ShellExecute() из AutoIt, которая, IMHO, работает через ж***. Вот только "Ex" ту совсем не нужна, достаточно "ShellExecute" с глаголом "open".

Код:
$File = InputBox('Run', 'Type the name of a program, folder, document, or Internet resource to open it', '', '', 368, 152)
If Not $File Then
	Exit
EndIf
$Ret = DllCall('shell32.dll', 'uint_ptr', 'ShellExecuteW', 'hwnd', 0, 'wstr', 'open', 'wstr', $File, 'ptr', 0, 'ptr', 0, 'int', @SW_SHOWNORMAL)
If @error Then
	$Ret = -1
Else
	If $Ret[0] <= 32 Then
		$Ret = $Ret[0]
	Else
		$Ret = 0
	EndIf
EndIf
If $Ret Then
	MsgBox(16, 'Error', 'Unable to open "' & $File & '".' & @CR & @CR & $Ret)
EndIf


Что означают те или иные коды ошибок, см. здесь.
 
Автор
V

VladUs

Скриптер
Сообщения
621
Репутация
181
То что и надо.
Всем спасибо за участие.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
Почему самопальную? Это правильная функция
Самопальная в том смысле что не встроенная (Built-in).

Вот только "Ex" ту совсем не нужна, достаточно "ShellExecute" с глаголом "open".
Для данной темы возможно и не нужна, а вот в целом очень даже нужна. Я эту функцию иногда использую для запуска ярлыка со “скрытым” пунктом назначения :smile: (например ярлык от Word).
 
Верх