我开发了一个c#代码段来确定虚拟(屏幕上)键盘是否显示。
以下代码在Windows 7,8和8.1中运行良好,但在Windows 10中,IsKeyboardVisible
始终返回true
...
public static bool IsKeyboardVisible() {
Process keyboardProc;
UInt32 WS_DISABLED = 0x8000000;
UInt32 WS_VISIBLE = 0X94000000;
int GWL_STYLE = -16;
IntPtr keyboardHandle = GetKeyboardWindowHandle();
bool visible = false;
if (keyboardHandle != IntPtr.Zero) {
UInt32 style = GetWindowLong(keyboardHandle, GWL_STYLE);
// in Win10, this always returns "true", i.e. WS_DISABLED is
//
//visible = ((style & WS_DISABLED) != WS_DISABLED);
// UPDATE: I found this code helping here
visible = (style == WS_VISIBLE);
}
return visible;
}
我在SO上使用了一个教程,但不久之前我很抱歉没有记下作者。
有没有人知道所有最新Windows版本的工作代码段,所以我不必检查实际的操作系统来打开版本......?
更新
我找到了original post here,它允许我更正代码。所以现在我的问题是旧的Win10问题 - 我无法使用
显示虚拟键盘string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath = Path.Combine(progFiles, "TabTip.exe");
keyboardProc = Process.Start(keyboardPath);
......再次,是否有任何"全平台"我可以使用的代码,或Win10的建议方法是什么?
更新2
我发现了在64位操作系统上运行32位应用程序的问题。话虽如此,我是否尝试在osk.exe
或" sysWOW64`文件夹中运行System32
时会出现错误...除了进行64位版本之外还有其他方法吗? ?
答案 0 :(得分:1)
在对TabTip.exe
,osk.exe
以及x86和x64兼容性问题进行了大量挖掘之后,我通过在我的系统上搜索osk.exe
并尝试运行每个问题找到了解决方案。我发现以下文件夹有4个版本:
C:\Windows\System32
C:\Windows\SysWOW64
C:\Windows\WinSxS\amd64_microsoft...
C:\Windows\WinSxS\wow64_microsoft...
看来C:\Windows\WinSxS\amd64_microsoft...
中的那个很好(不过其他三个)......
鉴于“amd64 _....”文件夹在不同的机器上可能不一样(我实际检查过它们并不匹配,我没有搜索这是否取决于机器,windows构建或其他任何东西...)。
所以基本上我做了一个小例程来查看WinSxS
文件夹并返回第一次出现的osk.exe
,这很正常。我还使用简单的OS架构测试使代码在32位操作系统上运行:
string OSKpath64 = getOskPath(@"C:\Windows\WinSxS");
if (string.IsNullOrWhiteSpace(OSKpath64)) {
OSKpath64 = "osk.exe";
}
string OSKpath32 = @"C:\Windows\System32\osk.exe";
if (!File.Exists(OSKpath32)) {
OSKpath32 = @"osk.exe";
}
System.Diagnostics.Process.Start((Environment.Is64BitOperatingSystem) ? OSKpath64 : OSKpath32);
<强>更新强>
WinSxS
文件夹中的一个工作版和一个非工作版的混淆让我感到紧张。它工作正常,因为amd_..
文件夹按字母顺序排在wow64_...
之前。
因此,我建议在getOskPath
方法中添加一个测试,以返回第一个本机64位osk.exe
(不是模拟的)。
使用IsWin64Emulator
method found here,方法如下所示:
static string getOskPath(string dir) {
string path = Path.Combine(dir, "osk.exe");
if (File.Exists(path)) {
Process p = System.Diagnostics.Process.Start(path);
if (p.IsWin64Emulator()) {
path = string.Empty;
}
p.Kill();
return path;
}
DirectoryInfo di = new DirectoryInfo(dir);
foreach (DirectoryInfo subDir in di.GetDirectories().Reverse()) {
path = getOskPath(Path.Combine(dir, subDir.Name));
if (!string.IsNullOrWhiteSpace(path)) {
return path;
}
}
return string.Empty;
}
答案 1 :(得分:0)
与我有同样的问题,我在这里尝试所有答案,但没有用。 用Google找到解决方案后,就可以了。
// Step 1: For Load On-Screen Keyboard
const string Kernel32dll = "Kernel32.Dll";
[DllImport(Kernel32dll, EntryPoint = "Wow64DisableWow64FsRedirection")]
public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
[DllImport(Kernel32dll, EntryPoint = "Wow64EnableWow64FsRedirection")]
public static extern bool Wow64EnableWow64FsRedirection(IntPtr ptr);
IntPtr wow64Value;
//---------------------------------------
// Step 2: Function-----
if (Environment.Is64BitOperatingSystem)
{
if (Wow64DisableWow64FsRedirection(ref wow64Value))
{
System.Diagnostics.Process.Start("osk.exe");
Wow64EnableWow64FsRedirection(wow64Value);
}
}
else
{
System.Diagnostics.Process.Start("osk.exe");
}
//----------------