Delphi 如何让ShellExecute使用超过57个字符的路径名?

Delphi 如何让ShellExecute使用超过57个字符的路径名?,delphi,Delphi,我正在尝试使用下面的代码从其目录启动quake,但是路径名超过50个字符,因此由于限制,它无法工作。是否还有更大的路径名 路径名示例 C:\Users\USERNAME\AppData\Roaming\Gaming\Toys\Q2\quake2.exe 谢谢ShellExecute不包含此限制,微软的雷蒙德·陈说 下面是编译为32位应用程序并在Windows 10上运行的XE8应用程序示例。(而且,尽管ShellExecute如Remy所说是启动可执行文件的错误方式,但它也向您展示了使用它和测试

我正在尝试使用下面的代码从其目录启动quake,但是路径名超过50个字符,因此由于限制,它无法工作。是否还有更大的路径名

路径名示例

C:\Users\USERNAME\AppData\Roaming\Gaming\Toys\Q2\quake2.exe


谢谢

ShellExecute不包含此限制,微软的雷蒙德·陈说

下面是编译为32位应用程序并在Windows 10上运行的XE8应用程序示例。(而且,尽管ShellExecute如Remy所说是启动可执行文件的错误方式,但它也向您展示了使用它和测试返回值错误的正确方式。)

单元1;
接口
使用
Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、,
Vcl.控件、Vcl.窗体、Vcl.对话框、Vcl.stdctrl;
类型
TForm1=类(TForm)
按钮1:t按钮;
程序按钮1点击(发送方:ToObject);
私有的
{私有声明}
公众的
{公开声明}
结束;
变量
表1:TForm1;
实施
{$R*.dfm}
使用
贝拉皮;
程序TForm1.按钮1单击(发送方:TObject);
变量
FilePath:string;
Res:整数;
开始
文件路径:=“C:\Users\Ken\Documents\Embarcadero\Studio\Projects\Seattle\Android\AndroidBase\Debug\Styles.xml”;
//使用长(96个字符)字符串作为参数,这是可行的
Res:=ShellExecute(0,'open','notepad.exe',PChar(FilePath),nil,SW_NORMAL);
如果Res<32,则
RAISELASTERROR(GetLastError);
//使用长(96个字符)字符串作为文件名,这是可行的
Res:=ShellExecute(0,'open',PChar(FilePath),nil,nil,SW_NORMAL);
如果Res<32,则
RAISELASTERROR(GetLastError);
结束;
结束。

从您上面的评论中可以看出,是地震本身产生了错误。在这种情况下,问题不是编程问题,而是您应该向软件供应商解决的问题。

您有什么具体问题?是什么让你觉得这是因为路径限制?您使用的是什么Delphi版本?为什么不检查ShellExecute的返回值以了解它失败的原因(假定它实际上失败了)?ShellExecute有一个路径长度限制,但该限制是2048(或者在不太可能的情况下,您仍然在Windows 95上运行时为260)。i、 路径长度57绝对不是你的问题。逻辑上也有一个基本缺陷。似乎已经确定文件已定位(FileFound=TRUE),但在此之后,将导出文件的路径。如果以前不知道该路径,或者该路径的派生方式不同,那么此时FileFound指示符似乎不可靠。我将添加一个FileExists()检查您认为将要打开的实际文件名。正如Ken所建议的,您不能简单地假设ShellExecute()失败的唯一原因是文件不存在。识别并报告真正的错误并采取行动。此外,无论如何,您不应该使用
ShellExecute()
启动
.exe
文件。您应该使用
CreateProcess()
相反。当应用程序与exe位于同一文件夹中时,我不知道它工作正常,但当我将其移出文件夹一侧时,它会说缺少文件可能参数字段影响了它mmmOk我修复了它非常感谢帮助人们在这里睡个好觉me@SimonWpgnLewis您说当您的应用程序处于与quake相同的文件夹,但不是其他虎钳,这是因为当您使用ShellExecute启动另一个应用程序时,该应用程序工作文件夹被设置为您自己应用程序的相同工作文件夹。这与您尝试使用未定义工作目录参数的快捷方式启动quake相同,在这种情况下,quake会将工作目录设置为快捷方式本身的位置。。。。。。。这就是为什么您应该改用CreateProcess,因为它允许您将已启动应用程序的工作目录设置为您自己选择的自定义位置。@Arioch:请参阅我刚才添加的链接。
procedure TAutoLauncher.OKBtnClick(Sender: TObject);
var
  parameters : string;
  toydir : string;
begin
  if FileFound then
  begin
    ToyDir := ExtractFilePath(ExtractFileDir(Application.ExeName)) + 'Toys\';
    FolderNameEdit.Text := ToyDir + 'Q2\quake2.exe';
    //
    parameters := Trim('');
    case ModeBox.ItemIndex of
      0: parameters := ' +connect '+ HostEdit.Text +':'+ PortEdit.Text +' +password '+ PasswordEdit.Text;
      1: parameters := ' +set game ctf';
      2: parameters := ' +set game rogue';
      3: parameters := ' +set game xatrix';
    end;
    //
    ShellExecute(handle, 'open', PChar(FolderNameEdit.Text), PChar(parameters), nil, SW_SHOWNORMAL);
   end else
   begin
     Application.MessageBox('Quake2 files not found.', 'Game Not Found', MB_OK OR MB_ICONQUESTION);
  end;
end;
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  ShellAPI;

procedure TForm1.Button1Click(Sender: TObject);
var
  FilePath: string;
  Res: Integer;
begin
  FilePath := 'C:\Users\Ken\Documents\Embarcadero\Studio\Projects\Seattle\Android\AndroidBase\Debug\Styles.xml';

  // This works, using the long (96 character) string as the parameters
  Res := ShellExecute(0, 'open', 'notepad.exe', PChar(FilePath), nil, SW_NORMAL);
  if Res < 32 then
    RaiseLastOSError(GetLastError);

  // This works, using the long (96 character) string as the filename
  Res := ShellExecute(0, 'open', PChar(FilePath), nil, nil, SW_NORMAL);
  if Res < 32 then
    RaiseLastOSError(GetLastError);

end;

end.