2

我目前正在设计一个图像查看器,它允许用户输入她的电子邮件并以数字方式获取图像。困扰我的部分是关闭屏幕键盘。我使用这段代码来启动windows进程:

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

之后,我打开一个 VB InputBox 以提示输入电子邮件地址(为此我使用屏幕键盘,因为应用程序将显示在触摸屏上)。在此提示之后,我想自动关闭该过程。

我尝试使用以下方法关闭该过程:

keyboardProc.Kill();
keyboardProc.Dispose();
keyboardProc.Close();
keyboardProc = null;

它们都不起作用,只是抛出异常:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll
Additional information: Cannot process request because the process has exited.

我还尝试通过 ID 识别进程并以这种方式关闭它,也没有工作。我还看了看: C#/.NET: Closing another process outside the main window but didn't get it working either.. :(

我对 C# 很陌生,这是我第一次从代码中调用 Windows 进程——我错过了什么吗?

非常感谢您!

4

4 回答 4

4
    /// <summary>
    /// Show the On Screen Keyboard
    /// </summary>
    #region ShowOSK
    public static void ShowOnScreenKeyboard()
    {
        ProcessStartInfo startInfo = new ProcessStartInfo(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
        Process.Start(startInfo);
    }
    #endregion ShowOSK

    /// <summary>
    /// Hide the On Screen Keyboard
    /// </summary>
    #region HideOSK
    public static void HideOnScreenKeyboard()
    {
        uint WM_SYSCOMMAND = 274;
        uint SC_CLOSE = 61536;
        IntPtr KeyboardWnd = FindWindow("IPTip_Main_Window", null);
        PostMessage(KeyboardWnd.ToInt32(), WM_SYSCOMMAND, (int)SC_CLOSE, 0);
    }
    #endregion HideOSK
于 2014-08-05T09:28:49.850 回答
2

我也遇到了麻烦。出于某种原因,这可行,尽管它会杀死所有打开的 TabTip 进程。

            //Kill all on screen keyboards
            Process[] oskProcessArray = Process.GetProcessesByName("TabTip");
            foreach (Process onscreenProcess in oskProcessArray)
            {
                onscreenProcess.Kill();
            }
于 2013-07-31T09:17:50.340 回答
2

与直接执行/关闭 TabTip.exe 相比,以下代码将最快地在 Window 10 上打开和关闭触摸键盘。(在低功耗平板电脑上测试)。

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("user32.dll", SetLastError = true)]
    static extern bool PostMessage(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern IntPtr FindWindow(String sClassName, String sAppName);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, String lpszClass, String lpszWindow);

    /// <summary>
    /// Show the On Screen Keyboard
    /// </summary>
    #region ShowOSK
    public static void ShowOnScreenKeyboard()
    {
        IntPtr parent = FindWindow("Shell_TrayWnd", null);
        IntPtr child1 = FindWindowEx(parent, IntPtr.Zero, "TrayNotifyWnd", "");
        IntPtr keyboardWnd = FindWindowEx(child1, IntPtr.Zero, "TIPBand", "Touch keyboard");

        uint WM_LBUTTONDOWN = 0x0201;
        uint WM_LBUTTONUP = 0x0202;
        UIntPtr x = new UIntPtr(0x01);
        UIntPtr x1 = new UIntPtr(0x0);
        IntPtr y = new IntPtr(0x0100020);
        PostMessage(keyboardWnd, WM_LBUTTONDOWN, x, y);
        PostMessage(keyboardWnd, WM_LBUTTONUP, x1, y);
    }
    #endregion ShowOSK

    /// <summary>
    /// Hide the On Screen Keyboard
    /// </summary>
    #region HideOSK
    public static void HideOnScreenKeyboard()
    {
        uint WM_SYSCOMMAND = 0x0112;
        UIntPtr SC_CLOSE = new UIntPtr(0xF060);
        IntPtr y = new IntPtr(0);
        IntPtr KeyboardWnd = FindWindow("IPTip_Main_Window", null);
        PostMessage(KeyboardWnd, WM_SYSCOMMAND, SC_CLOSE, y);
    }
    #endregion HideOSK
于 2016-01-09T11:33:16.400 回答
1

你可以:

            Process process = new Process();

            process.StartInfo.FileName = progFiles;//Filename
            process.Start();
            process.Close();
于 2013-05-30T11:30:00.913 回答