替代ShellExecuteW在64位Windows 7,8中

时间:2014-01-05 04:24:31

标签: delphi windows-8 delphi-xe windows-7-x64 shellexecute

我为32位和64位平台创建应用程序。

var
Form1: TForm1;
FilePath : string;

implementation

uses ShellAPI;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FilePath := ExtractFilePath(Application.ExeName);
.........................

procedure TForm1.MenuItem4Click(Sender: TObject);
var
  path_to_handbook : WideString;
begin
  case language of
    $0019 : path_to_handbook := FilePath+'help\handbook-ru.pdf'; // Russian
    $0009 : path_to_handbook := FilePath+'help\handbook-en.pdf'; // English
  end;
  ShellExecuteW(Handle, nil, PWideChar(path_to_handbook), nil, nil, SW_SHOWNORMAL);
end;

64位Windows 7或8中的函数ShellExecuteW不起作用!

我该如何解决它?

非常感谢!

3 个答案:

答案 0 :(得分:3)

在使用Win64作为目标进行编译时,我在自己的配置上遇到了同样的问题。

请尝试:

ShellExecuteW(Handle, 'open', PWideChar(path_to_handbook), nil, nil, SW_SHOWNORMAL);

我的意思是,明确将'open'而不是nil设置为lpOperation参数。对于Win64应用程序来说,似乎更适合我。

答案 1 :(得分:1)

您对ShellExecute的呼叫没有任何问题,ShellExecute在64位Windows上运行得非常好。由于它有效,因此无需替代ShellExecute

我可能会写这样的代码:

procedure TForm1.MenuItem4Click(Sender: TObject);
var
  langstr: string;
  path_to_handbook: string;
begin
  case language of
  $0019:
    langstr := 'ru';
  $0009: 
    langstr := 'en';
  else
    raise ESomeExceptionClass.Create('Unrecognised language');
  end;
  path_to_handbook := Format(
    '%shelp\handbook-%s.pdf', 
    [ExtractFilePath(Application.ExeName), langstr]
  );

  // mainly for debugging purposes
  if not FileExists(path_to_handbook) then
    raise ESomeExceptionClass.CreateFmt(
      'File not found: %s', 
      [path_to_handbook]
    );

  ShellExecute(Handle, nil, PChar(path_to_handbook), nil, nil, SW_SHOWNORMAL);
end;

我认为可以想象您的语言切换代码没有找到可识别的语言,而您的代码只是忽略了该失败,因为您的案例陈述中没有else子句。

另一种可能性是您的可执行文件位于C:\Windows\System32下,因此您的路径受文件系统重定向程序的约束。这肯定会让事情变得混乱,但肯定你没有犯下这样一个严重的错误,就是把你的可执行文件放在系统目录中。

但假设path_to_handbook是PDF文件的正确路径,如果您的代码失败,则问题是Acrobat文件关联而不是您的代码。换句话说,问题是环境问题。

答案 2 :(得分:0)

我使用ShellExecuteEx如下,它适用于我的Windows 7

procedure TAboutBox.WinexecAndWait(exeCutefile,paramstring:string);
var
   SEInfo: TShellExecuteInfo;
   ExitCode: DWORD;
begin
   if pos('http:',lowercase(executeFile))>0 then begin
     laAnswer.Caption:=executeFile;
     close;
   end;
   screen.Cursor:=crHourglass;
   FillChar(SEInfo, SizeOf(SEInfo), 0) ;
   SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
   with SEInfo do begin
     fMask := SEE_MASK_NOCLOSEPROCESS;    
     Wnd := Application.Handle;
     lpFile := PChar(ExecuteFile) ;
        { ParamString can contain the application parameters. }
     lpParameters := PChar(ParamString) ;
        { StartInString specifies the name of the working directory. 
    If ommited, the current directory is used. }
        // lpDirectory := PChar(StartInString) ;
     nShow := SW_SHOWNORMAL;
   end;
   if ShellExecuteEx(@SEInfo) then begin
     repeat
       Application.ProcessMessages;
       GetExitCodeProcess(SEInfo.hProcess, ExitCode) ;
     until (ExitCode <> STILL_ACTIVE) or  Application.Terminated;
   end else begin
     ShowMessage('Dji n''a nén polou fé çu ki fåt aveu '+executeFile)     ;
   end;
  screen.Cursor:=crDefault;
end;