简体   繁体   English

C#Windows 10虚拟键盘问题

[英]c# Windows 10 virtual keyboard issues

I have developed ac# code snippet to determine if the virtual (on-screen) keyboard was showing or not. 我已经开发了ac#代码段,以确定是否显示了虚拟(屏幕上)键盘。

The code below worked fine in Windows 7, 8 and 8.1, but in Windows 10, the IsKeyboardVisible always returns true ... 下面的代码在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;
}

I used a tutorial on SO, but it's a while ago so sorry for not crediting the author. 我使用了关于SO的教程,但是前一阵子很抱歉,我不相信作者。

Does anyone know about a working code snippet for all recent Windows versions, so I don't have to check the actual OS to switch on the version...? 有谁知道所有最新Windows版本的工作代码段,因此我不必检查实际的操作系统即可打开该版本...?

UPDATE 更新

I found the original post here , which allowed me to correct the code. 我在这里找到了原始帖子 ,这使我可以更正代码。 So now my problem is the same old Win10 issue - I can't show the virtual keyboard using 所以现在我的问题是相同的旧Win10问题-我无法使用

string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath = Path.Combine(progFiles, "TabTip.exe");
keyboardProc = Process.Start(keyboardPath);

... Again, is there any "all-platform" code I can use, or what is the suggested approach for Win10? ...同样,我可以使用任何“全平台”代码,或者Win10的建议方法是什么?

UPDATE 2 I found out about issues running a 32-bit application on a 64-bit os. 更新2我发现有关在64位操作系统上运行32位应用程序的问题。 That being said, the error occurs whether I try to run osk.exe in the System32 or the "sysWOW64` folder... Is there any other way than making a 64-bit release??? 话虽如此,无论我尝试在System32还是sysWOW64`文件夹中运行osk.exe ,都会发生错误...除了制作64位版本之外,还有其他方法吗???

After much digging about TabTip.exe , osk.exe and x86 and x64 compatibility issues, I found a solution by searching the osk.exe on my system and trying to run each of them. 在深入研究TabTip.exeosk.exe以及x86和x64兼容性问题之后,我找到了一个解决方案,方法是在系统上搜索osk.exe并尝试运行它们。 I found 4 version the following folders: 我在以下文件夹中找到了4版本:

  • C:\\Windows\\System32
  • C:\\Windows\\SysWOW64
  • C:\\Windows\\WinSxS\\amd64_microsoft...
  • C:\\Windows\\WinSxS\\wow64_microsoft...

It appears the one in C:\\Windows\\WinSxS\\amd64_microsoft... works fine (not the other three though)... 似乎在C:\\Windows\\WinSxS\\amd64_microsoft...工作正常(尽管不是其他三个)...

Given the "amd64_...." folder might not be the same on different machines (I actually checked and they don't match, I didn't search whether this depends on the machine, the windows build or anything else...). 鉴于“ amd64 _....”文件夹在不同的计算机上可能不相同(我实际上检查了它们,但它们不匹配,因此我没有搜索这是否取决于计算机,Windows构建或其他任何内容... )。

So basically I did a small routine to look into WinSxS folder and returning the very firs occurrence of osk.exe , which works just fine. 因此,基本上,我做了一个小例程来查看WinSxS文件夹并返回osk.exe出现,效果很好。 I also made the code working on a 32-bit OS using a simple OS-architecture test: 我还使用简单的OS体系结构测试使代码在32位OS上工作:

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

UPDATE: The confusion with one working and one non-working version within the WinSxS folder made me nervous. 更新: WinSxS文件夹中对一个可用版本和一个不可用版本的困惑使我感到紧张。 It works just fine because the amd_.. folder is alphabetically before wow64_... . 由于amd_..文件夹按字母顺序在wow64_...之前, wow64_...它可以正常工作。

I therefore suggest to add a test in the getOskPath method to return the first native 64-bit osk.exe (not the emulated one). 因此,我建议在getOskPath方法中添加一个测试以返回第一个本机64位osk.exe (而不是模拟的)。

Using the IsWin64Emulator method found here , the method looks like this: 使用此处找到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;
}

Same problem with me, I try all answer here, but it not work. 我遇到了同样的问题,我在这里尝试所有答案,但是没有用。 After finding solution with google, this is is ok. 用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");
            }
   //----------------

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM