【问题标题】:OnScreen keyboard issue with WPF Classic Windows App as Custom Shell on Windows 10 ProWPF 经典 Windows 应用程序作为 Windows 10 Pro 上的自定义外壳时出现屏幕键盘问题
【发布时间】:2017-12-26 21:20:15
【问题描述】:

我创建了一个 WPF 应用程序,它在 Windows 10 - Pro v. 1607 ASUS TP 201 平板电脑上作为自定义 shell 运行。

无法在 Windows 10 - Pro 中将经典 Windows 应用定义为自定义外壳。所以我修改了注册表,以便为自定义用户分配自定义 shell。

应用程序运行良好,但一旦在 TextBoxes 上触发触摸事件,虚拟键盘就不会弹出。在我的开发机器上进行测试时,它可以正常工作,并按预期提示键盘。即使将应用程序作为自定义 shell 运行,作为 windows shell 之后的应用程序,也可以正常工作。仅当应用作为自定义 shell 运行时,屏幕键盘才会失败。

我尝试过在 Tocuh 事件后启动键盘可执行文件的方法:

private void launchKeyboard(object sender, RoutedEventArgs e) 
{
   Process.Start(@"C:\[Path]\osk.exe");
}

此活动由以下人员发起:

<Textbox x:Name="textbox" GotFocus="launchKeyboard" ... />

但是:

1) 要启动 osk.exe,需要从 WinSxS 组件商店启动可执行文件,因为 osk.exe 是在 64 位上运行的 32 位应用程序。需要注意的是,WinSxS 中的文件夹以包含哈希的长字符串命名。所以我不能为每个平板电脑指定启动路径,因为每个平板电脑都有一个自定义名称。

2)要启动tabtip.exe,我需要以管理员权限启动该进程,这样做,应用程序会提示一个需要管理员密钥的对话框,由于平板电脑用户不这样做,因此无法完成拥有管理员权限。

3) 安装了一个授权的自定义键盘,tabtipondemand,和 2 一样,需要管理员密钥。

我想知道为什么要启动 tabtip.exe,需要管理员级别。

 Process.Verb = "runas";

如果不使用管理员启动,则虚拟键盘失败,只会出现空对话框。

所以我的问题是:

1) 如何在作为自定义 shell 运行的经典 Windows WPF 应用程序中启动 tabtip.exe,无需管理员的 Windows 10 原生屏幕键盘。

2) 如何定义通用或动态路径以从 Windows 组件存储 WinSxS 启动 osk.exe,而不是为每台机器自定义每个路径。

3) 我可以在我的应用程序中编译任何库 dll 以在应用程序在 Windows shell 上运行时启用 tabtip.exe 的本机行为吗?

让我明确一点:

1) 我将 Windows 经典应用程序作为自定义 shell 运行,而不是 UWA。

2) 应用程序应作为自定义 shell 运行的机器是 Windows 10 - Pro v 1607、触摸屏、Asus tp201。

3) 自定义 shell 未从任何应用商店或信息亭模式运行。由于许可复杂性,经典 Windows 应用无法在 Windows 10 专业版上作为自定义 shell 运行。

4) 自定义shell是通过修改寄存器来配置的,效果很好,没有问题。

5) 目前无法将我们的原生 WPF 应用程序迁移到 UWA。有一些关于使用 UWA 定制 shell 的 som PITA。

【问题讨论】:

    标签: c# wpf windows-10


    【解决方案1】:

    我设法找到了一个完美的解决方案来解决在 Windows 10 上作为自定义 shell 运行的 Windows 桌面应用程序中显示虚拟键盘的问题。

    考虑到作为自定义 shell 运行,Windows 10 本机虚拟键盘不会显示,我使用了一个由 Alexei SherbakovGithub 上共享的名为 osklib 的便捷库>。它也可以作为 Nuget PM 中的一个包提供,可以在 VS 中使用。

    添加 Osklib 作为对您项目的引用,并使用 Gotfocus 事件从任何表单触发事件,该事件属于 System.Windows.Forms 命名空间:

    <TextBox ... Gotfocus="TriggerKeyboard" />
    

    然后创建调用 Osklib 类的 TriggerKeyboard 事件:

    private void TriggerKeyboard(object sender, EventArgs e) {
         try {
            Osklib.OnScreenKeyboard.Show();
         } 
        catch(Exception ex) {
           MessageBox.Show(ex.Message);
        }
     }
    

    这一切都是快速、简单且防故障的。感谢阿列克谢。

    【讨论】:

      猜你喜欢
      • 2017-01-29
      • 2018-11-03
      • 1970-01-01
      • 2015-11-11
      • 2016-02-13
      • 1970-01-01
      • 2010-11-13
      • 2016-05-01
      • 1970-01-01
      相关资源
      最近更新 更多