osk.exe
90%の確率で、の32ビットプロセスから起動できませんWin7 x64
。元々、コードは次のものを使用していました。
Process.Launch("osk.exe");
これは、ディレクトリの仮想化のためにx64では機能しません。私が思った問題ではありません。仮想化を無効にしてアプリを起動し、再度有効にするだけです。これが正しい方法だと思いました。また、キーボードが最小化されている場合にキーボードを元に戻すためのコードも追加しました(これは正常に機能します)。コード(サンプルのWPFアプリ内)は次のようになります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;using System.Diagnostics;
using System.Runtime.InteropServices;
namespace KeyboardTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);
private const UInt32 WM_SYSCOMMAND = 0x112;
private const UInt32 SC_RESTORE = 0xf120;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
private string OnScreenKeyboadApplication = "osk.exe";
public MainWindow()
{
InitializeComponent();
}
private void KeyboardButton_Click(object sender, RoutedEventArgs e)
{
// Get the name of the On screen keyboard
string processName = System.IO.Path.GetFileNameWithoutExtension(OnScreenKeyboadApplication);
// Check whether the application is not running
var query = from process in Process.GetProcesses()
where process.ProcessName == processName
select process;
var keyboardProcess = query.FirstOrDefault();
// launch it if it doesn't exist
if (keyboardProcess == null)
{
IntPtr ptr = new IntPtr(); ;
bool sucessfullyDisabledWow64Redirect = false;
// Disable x64 directory virtualization if we're on x64,
// otherwise keyboard launch will fail.
if (System.Environment.Is64BitOperatingSystem)
{
sucessfullyDisabledWow64Redirect = Wow64DisableWow64FsRedirection(ref ptr);
}
// osk.exe is in windows/system folder. So we can directky call it without path
using (Process osk = new Process())
{
osk.StartInfo.FileName = OnScreenKeyboadApplication;
osk.Start();
osk.WaitForInputIdle(2000);
}
// Re-enable directory virtualisation if it was disabled.
if (System.Environment.Is64BitOperatingSystem)
if (sucessfullyDisabledWow64Redirect)
Wow64RevertWow64FsRedirection(ptr);
}
else
{
// Bring keyboard to the front if it's already running
var windowHandle = keyboardProcess.MainWindowHandle;
SendMessage(windowHandle, WM_SYSCOMMAND, new IntPtr(SC_RESTORE), new IntPtr(0));
}
}
}
}
しかし、このコードは、ほとんどの場合、次の例外をスローしますosk.Start()
。
指定されたプロシージャがSystem.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)で見つかりませんでした
競合状態ではないことを確認するために、osk.Start行の周りに長いThread.Sleepコマンドを配置しようとしましたが、同じ問題が解決しません。誰かが私が何か間違ったことをしているところを見つけたり、これに対する代替の解決策を提供したりできますか?メモ帳を起動しても問題なく動作するようですが、オンスクリーンキーボードではボールを再生できません。