I'm currently designing an image viewer that allows the user to input her e-mail and get the images digitally. The part that troubles me is getting the on-screen keyboard to close. I use this piece of code to start the windows process:
string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath = Path.Combine(progFiles, "TabTip.exe");
Process keyboardProc = Process.Start(keyboardPath);
After which i open a VB InputBox to prompt for the e-mail address (for which i use the on-screen keyboard, since the application will be shown on a touch screen). After this prompt I want to close the process automatically.
I've tried to close the process with the following:
keyboardProc.Kill();
keyboardProc.Dispose();
keyboardProc.Close();
keyboardProc = null;
None of them works and simply throws the exception:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll
Additional information: Cannot process request because the process has exited.
I also tried identifying the process by ID and closing it this way, didn't work either.
I also had a look at:
C#/.NET: Closing another process outside the main window
but didn't get it working either.. :(
I'm pretty new to C# and this is the first time I've invoked a windows process from code - am I missing something?
Thank you very much in advance!
u can do:
Process process = new Process();
process.StartInfo.FileName = progFiles;//Filename
process.Start();
process.Close();
I had trouble with this too. For some reason this works, although it kills all open TabTip processes.
//Kill all on screen keyboards
Process[] oskProcessArray = Process.GetProcessesByName("TabTip");
foreach (Process onscreenProcess in oskProcessArray)
{
onscreenProcess.Kill();
}
/// <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
The following code will open/close Touch Keyboard on Window 10 the quickest, compared to executing/closing TabTip.exe directly. (tested on low power tablet).
[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, null, "Touch keyboard");
uint WM_LBUTTONDOWN = 0x0201;
uint WM_LBUTTONUP = 0x0202;
UIntPtr x = new UIntPtr(0x01);
UIntPtr x1 = new UIntPtr(0);
IntPtr y = new IntPtr(0x0240012);
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