-1

以下代码不会使应用程序运行。有人可以指出可能是什么问题吗?

procedure TTestForm1.DR_DBA_StartAppButtonClick(Sender: TObject);
var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  filename : String;
  sa : TSecurityAttributes;
  sd : TSecurityDescriptor;

begin

  InitializeSecurityDescriptor( @sd, SECURITY_DESCRIPTOR_REVISION );
  SetSecurityDescriptorDacl( @sd, true, nil, false);

  sa.nLength := sizeof( sa );
  sa.lpSecurityDescriptor := @sd;
  sa.bInheritHandle := true;

  // start app process
  ZeroMemory(@StartInfo, SizeOf(TStartupInfo));
  StartInfo.cb := SizeOf(TStartupInfo);

  if not
    CreateProcess (nil, PChar(SF_AppPathBox.Text), @sa, @sa, False,
    PROCESS_VM_WRITE or PROCESS_VM_OPERATION, nil, nil, StartInfo, ProcInfo) then
  begin

    showmessage ('Cannot Start App');
    exit;

  end;

end;

这段代码在具有不同 UI 的旧 alpha 版本中运行得非常好,但现在在实施新的 UI 设计之后,它就不行了。

GetLastError 函数返回错误代码 2,系统找不到指定的文件。

定义的路径是正确的,因为它是从应用程序创建的 installdir 注册表项中提取的。我也尝试过手动包含它,但无济于事。

'X:\App\PB 0.93\PB.exe'

我使用 DxScene v4.42 进行 UI 设计,路径是从 TVxTextBox 中提取的。输入恒定路径有效,但不是从文本框中输入,尽管两者都是系统字符串。我通过 CompareStr 将两个字符串相互比较,结果完全匹配。

我正在使用 Windows 7 64/32 位和 Windows XP SP2/3 32 位。

发现

DxScene 组件固有地使用与 createprocess 过程不兼容的 unicode 字符串。

所以我首先将所需的路径字符串存储在普通字符串中,然后将它们作为参数传递以创建有效的过程。

4

1 回答 1

3

您似乎在 Unicode 和 Ansi 文本之间存在不匹配。您正在使用使用 Unicode 的 UI 控件,但在 Ansi Delphi 中进行编译。因此,您将一个 16 位字符的数组传递给一个需要 8 位编码文本的函数。这解释了报告的错误代码。

该代码可能适用于原始开发人员,因为他们使用了现代 Unicode Delphi。如果是这种情况,那么您最好的做法是使用最初编译代码的 Delphi 版本来编译代码。

如果您必须使用 Ansi Delphi,那么您可以通过传递来修复您的代码

PChar(string(SF_AppPathBox.Text))

创建进程。这将产生从 Unicode 转换为 Ansi 的效果。

您也可以像这样调用 Unicode 版本的 CreateProcess:

CreateProcessW(..., PWideChar(WideString(SF_AppPathBox.Text)), ...)
于 2012-08-15T10:29:42.800 回答