即使以管理员的身份运行Visual Studio后,请求的操作也需要高程



我正在尝试从我的winform应用程序运行和调整OSK大小,但我遇到了此错误:

请求的操作需要高程。

我正在以管理员的身份运行Visual Studio。

System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = "c:\windows\system32\osk.exe";
process.StartInfo.Arguments = "";
process.StartInfo.WorkingDirectory = "c:\";
process.Start(); // **ERROR HERE**
process.WaitForInputIdle();
SetWindowPos(process.MainWindowHandle,
this.Handle, // Parent Window
this.Left, // Keypad Position X
this.Top + 20, // Keypad Position Y
panelButtons.Width, // Keypad Width
panelButtons.Height, // Keypad Height
SWP_SHOWWINDOW | SWP_NOZORDER); // Show Window and Place on Top
SetForegroundWindow(process.MainWindowHandle);

但是,

System.Diagnostics.Process.Start("osk.exe"); 

工作正常,但它不会让我调整键盘大小

process.StartInfo.UseShellExecute = false将禁止您做您想做的事情。osk.exe有点特别,因为只有一个实例可以一次运行。因此,您必须让操作系统处理启动(UseShellExecute必须为true)。

(...)工作正常,但它不会让我调整键盘大小

只需确保process.MainWindowHandle不是IntPtr.Zero即可。不过,可能需要一段时间,您不允许您使用process.WaitForInputIdle()询问该过程实例,这可能是因为PROC由OS运行。您可以对句柄进行轮询,然后运行代码。这样:

System.Diagnostics.Process process = new System.Diagnostics.Process();
// process.StartInfo.UseShellExecute = false;
// process.StartInfo.RedirectStandardOutput = true;
// process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = "c:\windows\system32\osk.exe";
process.StartInfo.Arguments = "";
process.StartInfo.WorkingDirectory = "c:\";
process.Start(); // **ERROR WAS HERE**
//process.WaitForInputIdle();
//Wait for handle to become available
while(process.MainWindowHandle == IntPtr.Zero)
    Task.Delay(10).Wait();
SetWindowPos(process.MainWindowHandle,
this.Handle, // Parent Window
this.Left, // Keypad Position X
this.Top + 20, // Keypad Position Y
panelButtons.Width, // Keypad Width
panelButtons.Height, // Keypad Height
SWP_SHOWWINDOW | SWP_NOZORDER); // Show Window and Place on Top
SetForegroundWindow(process.MainWindowHandle);

适当的注意:使用Wait()(或Thread.Sleep);Winforms应该非常有限,它会使UI线程无响应。您可能应该在此处使用Task.Run(async () => ...,以便能够使用await Task.Delay(10),但这是一个不同的故事并使代码稍微复杂化。

最新更新