gpt4 book ai didi

windows - 从 Delphi 启动 Windows 优化应用程序 (Windows 10)

转载 作者:可可西里 更新时间:2023-11-01 10:54:25 25 4
gpt4 key购买 nike

我们有一个遗留的 Delphi 7 应用程序,它启动 Windows 碎片整理和屏幕键盘应用程序,如下所示:

// Defragmentation application
ShellExecute(0, 'open', PChar('C:\Windows\System32\dfrg.msc'), nil, nil, SW_SHOWNORMAL);

// On-screen keyboard
ShellExecute(0, 'open', PChar('C:\Windows\System32\osk.exe'), nil, nil, SW_SHOWNORMAL);

两者都在 Windows XP 上工作,但在 Windows 10 上失败。我发现碎片整理应用程序的名称已更改为 dfrgui.exe,但更新代码没有帮助。屏幕键盘在 Windows 10 上仍称为 osk.exe

这两个应用程序都可以手动/直接从命令行或通过在 Windows 资源管理器中双击它们来启动。

我怀疑 Windows 安全性阻止我的应用程序从 C:\Windows\System32 启动任何东西,因为我可以从 Program Files 和从C:\Windows

有人能帮忙吗?

最佳答案

Delphi 7 仅生成 32 位应用程序,没有生成 64 位应用程序的选项(在 XE2 中添加)。

从 64 位系统上运行的 32 位应用程序访问 %WINDIR%\System32 下的路径受 WOW64 的 File System Redirector 约束。 ,它将以静默方式将对 64 位 System32 文件夹的请求重定向到 32 位 SysWOW64 文件夹。

很可能,您尝试运行的应用仅存在于 64 位 System32 文件夹中,而不存在于 32 位 SysWOW64 文件夹中。

要避免重定向,您需要:

  • System32 替换为路径中的特殊 Sysnative 别名(即 'C:\Windows\Sysnative\osk.exe'),它仅在 WOW64 下运行时有效,因此您必须在运行时通过 IsWow64Process() 动态检测它:

    function GetSystem32Folder: string;
    var
    Folder: array[0..MAX_PATH] of Char;
    IsWow64: BOOL;
    begin
    Result := '';
    if IsWow64Process(GetCurrentProcess(), @IsWow64) and IsWow64 then
    begin
    SetString(Result, Folder, GetWindowsDirectory(Folder, Length(Folder)));
    if Result <> '' then
    Result := IncludeTrailingPathDelimiter(Result) + 'Sysnative' + PathDelim;
    end else
    begin
    SetString(Result, Folder, GetSystemDirectory(Folder, Length(Folder)));
    if Result <> '' then
    Result := IncludeTrailingPathDelimiter(Result);
    end;
    end;

    function RunDefrag: Boolean;
    var
    SysFolder: string;
    Res: Integer;
    begin
    SysFolder := GetSystem32Folder;
    Res := Integer(ShellExecute(0, nil, PChar(SysFolder + 'dfrgui.exe'), nil, nil, SW_SHOWNORMAL));
    if Res = ERROR_FILE_NOT_FOUND then
    Res := Integer(ShellExecute(0, nil, PChar(SysFolder + 'dfrg.msc'), nil, nil, SW_SHOWNORMAL));
    Result := (Res = 0);
    end;

    function RunOnScreenKeyboard: Boolean;
    begin
    Result := (ShellExecute(0, nil, PChar(GetSystem32Folder + 'osk.exe'), nil, nil, SW_SHOWNORMAL) = 0);
    end;
  • 通过 Wow64DisableWow64FsRedirection() 暂时禁用重定向器, 然后通过 Wow64RevertWow64FsRedirection() 重新启用它完成后:

    function GetSystem32Folder: string
    var
    Folder: array[0..MAX_PATH] of Char;
    begin
    SetString(Result, Folder, GetSystemDirectory(Folder, Length(Folder)));
    if Result <> '' then
    Result := IncludeTrailingPathDelimiter(Result);
    end;

    function RunDefrag: Boolean;
    var
    SysFolder: string;
    OldState: Pointer;
    Res: Integer;
    begin
    Wow64DisableWow64FsRedirection(@OldState);
    try
    SysFolder := GetSystem32Folder;
    Res := Integer(ShellExecute(0, nil, PChar(SysFolder + 'dfrgui.exe'), nil, nil, SW_SHOWNORMAL));
    if Res = ERROR_FILE_NOT_FOUND then
    Res := Integer(ShellExecute(0, nil, PChar(SysFolder + 'dfrg.msc'), nil, nil, SW_SHOWNORMAL));
    Result := Res = 0;
    finally
    Wow64RevertWow64FsRedirection(OldState);
    end;
    end;

    function RunOnScreenKeyboard: Boolean;
    var
    OldState: Pointer;
    begin
    Wow64DisableWow64FsRedirection(@OldState);
    try
    Result := (ShellExecute(0, nil, PChar(GetSystem32Folder + 'osk.exe'), nil, nil, SW_SHOWNORMAL) = 0);
    finally
    Wow64RevertWow64FsRedirection(OldState);
    end;
    end;

更新:话虽如此,事实证明,在启用 UAC 时,不允许在 WOW64 下运行的 32 位进程运行 osk.exe:

Delphi - On Screen Keyboard (osk.exe) works on Win32 but fails on Win64

因此,当应用程序在 WOW64 下运行时,您必须创建一个 64 位辅助进程来代表您的应用程序启动 osk.exe

关于windows - 从 Delphi 启动 Windows 优化应用程序 (Windows 10),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50993705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com