- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试从我的应用程序运行屏幕键盘。它在 Windows XP 32 位下正常工作,但在 Win 7 64 位下不正确。
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ShellAPI;
type
TForm5 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
class function IsWOW64: Boolean;
{ Public declarations }
end;
var
Form5: TForm5;
implementation
{$R *.dfm}
procedure TForm5.FormCreate(Sender: TObject);
var path:String;
res : Integer;
function GetSysDir: string;
var
Buf: array[0..MAX_PATH] of Char;
Len: UINT;
S: String;
begin
{$IFNDEF WIN64}
if TForm5.IsWOW64 then
begin
Len := GetWindowsDirectory(Buf, MAX_PATH);
if Len = 0 then RaiseLastOSError;
SetString(S, Buf, Len);
Result := IncludeTrailingPathDelimiter(S) + 'Sysnative\';
Exit;
end;
{$ENDIF}
Len := GetSystemDirectory(Buf, MAX_PATH);
if Len = 0 then RaiseLastOSError;
SetString(S, Buf, Len);
Result := IncludeTrailingPathDelimiter(S);
end;
begin
path := GetSysDir;
path := path + 'osk.exe';
res := ShellExecute(self.Handle,'open',Pchar(path),nil,nil,SW_NORMAL);
if res <> 42 then
begin
ShowMessage(path);
RaiseLastOSError;
end;
end;
class function TForm5.IsWOW64: Boolean;
type
TIsWow64Process = function( // Type of IsWow64Process API fn
Handle: THandle;
var Res: BOOL
): BOOL; stdcall;
var
IsWow64Result: BOOL; // result from IsWow64Process
IsWow64Process: TIsWow64Process; // IsWow64Process fn reference
begin
// Try to load required function from kernel32
IsWow64Process := GetProcAddress(
GetModuleHandle('kernel32'), 'IsWow64Process'
);
if Assigned(IsWow64Process) then
begin
// Function is implemented: call it
if not IsWow64Process(GetCurrentProcess, IsWow64Result) then
RaiseLastOSError;
// Return result of function
Result := IsWow64Result;
end
else
// Function not implemented: can't be running on Wow64
Result := False;
end;
end.
在 x64 下运行应用程序会显示路径 C:\Windows\Sysnative\osk.exe ,并引发“调用操作系统函数失败”错误。
搜索 Windows 目录显示 osk.exe 存在
最佳答案
UAC 下的 osk 有一些特别之处。此代码失败,错误代码为 740、ERROR_ELEVATION_REQUIRED
、请求的操作需要提升。
var
si: TStartupInfo;
pi: TProcessInformation;
....
si.cb := SizeOf(si);
GetStartupInfo(si);
Win32Check(CreateProcess('C:\Windows\system32\osk.exe', nil, nil, nil,
False, 0, nil, nil, si, pi));
在具有 UAC 的计算机上,这在 32 位和 64 位进程下都会失败。您可以在这里找到有关该问题的一些讨论:https://web.archive.org/web/20170311141004/http://blog.delphi-jedi.net/2008/05/17/the-case-of-shellexecute-shellexecuteex-createprocess-and-oskexe/
所以你的问题与32位或64位无关,而是由于你的XP系统没有UAC。
更广泛地说,我认为这应该足以说服您永远不再调用 ShellExecute
。它的存在只是为了 16 位兼容性,并且在报告错误方面毫无用处。如果您希望出现错误,请调用ShellExecuteEx
。但是,由于我们正在启动一个新流程,因此 CreateProcess
通常是正确调用的 API。
也就是说,在这种特定情况下,osk 的设计使其无法通过 CreateProcess
以编程方式启动。它确实需要由 ShellExecute
或 ShellExecuteEx
调用。这使得 shell 能够发挥其 UAC 魔力。现在,事实证明 32 位 WOW64 进程无法实现奇迹。解决方案是通过调用 ShellExecuteEx 从 64 位进程启动 osk。
这是您的解决方法:
ShellExecuteEx
即可打开 osk
。ShellExecuteEx
来打开osk
。ShellExecuteEx
来打开 osk
。 由于您似乎没有使用 64 位版本的 Delphi,因此您需要找到 64 位编译器。您可以使用 64 位 fpc 或 64 位 C++ 编译器。下面的 C++ 程序就足够了:
#include <Windows.h>
#include <Shellapi.h>
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
SHELLEXECUTEINFOW sei = { sizeof(sei) };
sei.lpVerb = L"open";
sei.lpFile = L"osk.exe";
sei.nShow = SW_SHOW;
ShellExecuteExW(&sei);
}
您可以使用 64 位 C++ 编译器对其进行编译,然后从 32 位 WOW64 进程中调用它。我知道很啰嗦,但它确实有实际工作的优点!
关于Delphi - 屏幕键盘 (osk.exe) 在 Win32 上工作,但在 Win64 上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23116149/
我正在尝试编写一个桌面应用程序,如果我单击某些按钮,OSK 将出现。我尝试使用以下代码调用它: System.Diagnostics.Process.Start("osk.exe"); 但是每次都显示
我正在开发一个 Kiosk 类型(没有鼠标,没有键盘)的应用程序,用户可以在其中将数据输入到 Excel 电子表格中。我想让屏幕键盘每次被调用时都出现在同一个地方。 osk.exe 窗口“记住”它在关
又是这些问题之一(从 chrome 网络浏览器执行 local.exe 文件)。 我知道这是不可能的(至少不是简单的方法) 我想做的是打开文件夹中存放的windows机器上的虚拟键盘 c:/windo
我有一个在 webview 中运行的角度应用程序和一个在 uwp 中的自定义屏幕键盘 (OSK)。我无法使用自定义 OSK 在 webview 中存在的文本框中输入数据,尽管它对于普通 UWP 文本框
我一直在尝试让屏幕键盘 (osk.exe) 在我的应用程序中出现(和消失)在 Windows 10 上。我的应用程序在 Windows 7 中运行良好。在 osk.exe 上调用 ShellExecu
我用下面的代码打开osk.exe HINSTANCE Dlg::ExecuteOSK() { typedef BOOL (WINAPI * LPFN_IsWow64Process)(HANDL
我正在尝试创建一个 OSX 应用程序,它将是屏幕键盘的复制品。是否可以将一些文本插入到另一个事件应用程序的光标位置?提前致谢! 最佳答案 这是可能的。辅助功能允许更改其他应用程序的内容,但您的应用程序
我制作了这个小的 .ps1 脚本,因为它允许我在不使用编译器(至少直接使用)的情况下运行 C#。我想移动使用 cmd/c osk.exe 打开的“辅助功能屏幕键盘”,因为我不能真正使用 TabTip
90% 的时间我无法从 Win7 x64 上的 32 位进程启动 osk.exe。最初代码只是使用: Process.Launch("osk.exe"); 由于目录虚拟化,这在 x64 上不起作用。我
我正在尝试从我的应用程序运行屏幕键盘。它在 Windows XP 32 位下正常工作,但在 Win 7 64 位下不正确。 unit Unit5; interface uses Windows,
我正在开发一个 WPF 应用程序,我想在其中以“始终存在”的方式显示内置的 Windows 7 屏幕键盘。所以我想: 将其移动到特定位置 设置为一定的宽高 移除标题/标题栏,这样用户就无法移动或关闭它
我是一名优秀的程序员,十分优秀!