c# Windows 10虚拟键盘问题

本文关键字:键盘 问题 虚拟 Windows | 更新日期: 2023-09-27 18:16:24

我已经开发了一个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版本的工作代码片段,所以我不必检查实际的操作系统来切换版本…?

我在这里找到了原始帖子,这使我能够纠正代码。所以现在我的问题是同样的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位应用程序的问题。话虽如此,无论我试图在System32或"sysWOW64"文件夹中运行osk.exe,都会出现错误……除了做64位版本,还有其他方法吗?

c# Windows 10虚拟键盘问题

在深入研究了TabTip.exeosk.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的第一次出现,这工作得很好。我还使用一个简单的操作系统架构测试使代码在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方法,该方法看起来像这样:

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;
}

我也有同样的问题,我在这里尝试了所有的答案,但它不起作用。在谷歌找到解决方案后,这是ok的。

// 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");
            }
   //----------------