ShellExecuteEx возвращает 42 в hInstApp при ожидании 31 (нет ассоциации файлов) - PullRequest
0 голосов
/ 26 сентября 2011

Когда я использую ShellExecuteEx в Delphi 7 для открытия файла с помощью глагола, я всегда получаю 42 обратно в результате в hInstApp, хотя я ожидаю получить ошибку и 31 результат, так как нет файловая ассоциация. Я перехожу из ShellExecute в ShellExecuteEx, чтобы я мог использовать WaitForInputIdle с дескриптором процесса.

ShellExecute возвращает 31, как и ожидалось, когда я пытаюсь открыть файл XLS, когда у меня не установлен Excel, но ShellExecuteEx, кажется, успешно и возвращает 42, несмотря на то, что он фактически потерпел неудачу и выскочил диалоговое окно ассоциации файлов Windows по умолчанию.

Я что-то не так делаю? Использование Delphi 7 в WinXP и Win7.

Пример кода ниже. Использование Delphi 7 на 32-битной ОС Win XP, но также получение тех же результатов на 64-битной Win 7. Простое отображение сообщения для значения hInstApp возвращает 42, когда я ожидаю получить 31, поскольку у меня не установлен Excel.

var
  ExecInfo: TShellExecuteInfo;
begin
  ZeroMemory(ExecInfo, sizeof(ExecInfo));
  with ExecInfo do
  begin
    cbSize := sizeOf(ExecInfo);
    fMask  := SEE_MASK_NOCLOSEPROCESS;
    lpVerb := PChar('open');
    lpFile := PChar('c:\windows\temp\test.xls');
    nShow  := 1;
  end;
  ShellExecuteEx(@ExecInfo);
  if ExecInfo.hInstApp<32
  then WaitForInputIdle(ExecInfo.hProcess, 10000);
end;

Ответы [ 3 ]

1 голос
/ 26 сентября 2011

Возвращаемые значения ShelLExecuteEx не совпадают с ShelLExecute. Прочитайте документацию здесь: http://msdn.microsoft.com/en-us/library/bb762154%28v=VS.85%29.aspx. Также убедитесь, что вы установили правильные флаги в SHELLEXECUTEINFO для правильного поведения при возникновении ошибки.

0 голосов
/ 16 марта 2016

Нехпец: "это явно не удалось". На самом деле, он имеет: он успешно запустил RunDll32.Exe.

Убедитесь, что член fMask содержит SEE_MASK_FLAG_DDEWAIT. Если это не так. Вы можете увидеть диалог «Открыть с помощью».

0 голосов
/ 26 сентября 2011

Функция ZeroMemory должна вызываться с указателем в качестве параметра:

ZeroMemory(@ExecInfo, sizeof(ExecInfo));

Тогда я бы использовал результат Shell ExecuteEx для продолжения:

if (ShellExecuteEx(@ExecInfo)) then

Насколько я знаю, вы должны закрыть ручку в конце:

CloseHandle(ExecInfo.hProcess);

Вызов функции с глаголом, установленным на ноль, скажет Windows использовать стандартный глагол, он немного более общий, чем «открытый».

Я сделал пример для ожидания завершения приложения, но вы могли легко заменить WaitForSingleObject на WaitForInputIdle.

...