Запуск процесса без кражи фокуса (C #) - PullRequest
16 голосов
/ 23 января 2010

Мне нужно иметь возможность запускать процессы (как консольные, так и оконные) без кражи фокуса. Единственный способ в .NET Framework, который я нашел, - это Microsoft.VisualBasic.Interaction.Shell с Microsoft.VisualBasic.AppWinStyle. [Minimized | Normal] NoFocus (который отображается в SW_SHOWMINNOACTIVE / SW_SHOWMA, передаваемый в ShellExecute). 1001 *

В текущей версии моего кода (который ворует фокус) я использую System.Diagnostics.Process и полагаюсь на некоторые функции, которые мне дают, чего нет у метода Interaction.Shell.

2 вопроса (один серьезный, а другой выражает мое разочарование, на которое я действительно не ожидаю хорошего ответа)

1.) Правильно ли я понимаю, что у меня нет другого выбора, кроме как самим оборачивать CreateProcess или ShellExecuteEx, или мне не хватает другого решения? Я действительно надеялся избежать этого, так как Process - такая полная и полезная оболочка, кроме этого упущения, и было бы так много функциональности, которую нужно реализовать, P / Invoke, вызовы для отладки и всякие разные боли.

2.) Почему одна команда в Microsoft создала такую ​​(иначе) полную обертку, а затем исключила половину возможных значений из ProcessWindowStyle, тогда как другая команда создала подобную обертку, которая была гораздо менее полной, но предоставила все полезные стили окон?

Ответы [ 2 ]

12 голосов
/ 23 января 2010

Команда VB.Net сделала гораздо больше, чтобы упростить для разработчика вопросы, касающиеся инструментария Windows, и я не вижу проблем с добавлением ссылки на VB dll и использованием ее в вашей программе на C #.

Это две команды с разной направленностью, вот и все. И вы не должны расстраиваться из-за использования Microsoft.VisualBasic.Interaction.Shell, если это решит вашу проблему.

Вы также можете использовать Reflector, чтобы увидеть фактическую реализацию и реализовать код самостоятельно, если не хотите ссылаться на dll.

[Правка - после кода добавлен пример кода, показывающий, что вы можете комбинировать Interaction.Shell и Process]

int pid = Interaction.Shell("notepad.exe", AppWinStyle.NormalFocus);
Process p = Process.GetProcessById(pid);
p.Exited += ((o, e) => Console.WriteLine("Exit"));
p.EnableRaisingEvents = true;
Console.ReadLine();

Здесь я использую метод Shell, чтобы запустить процесс, получить дескриптор процесса из pid и подключить события. Вы даже можете сделать p.Kill (), чтобы прервать процесс.

[Правка - обходной путь для cmd.exe]

Это начинает становиться немного хакерским на мой вкус, но это работает. Замените «NEWWINDOW» на случайную направляющую или что-то в этом роде, чтобы сделать ее уникальной.

Microsoft.VisualBasic.Interaction.Shell(@"cmd.exe /c ""start cmd.exe /k title NEWWINDOW""", AppWinStyle.NormalFocus);
foreach (var process in Process.GetProcessesByName("cmd"))
{
    if (process.MainWindowTitle.EndsWith("NEWWINDOW"))
    {
        process.Exited += ((o, e) => Console.WriteLine("Exit"));
        process.EnableRaisingEvents = true;
    }
}
2 голосов
/ 23 января 2010

Посмотрите здесь:

System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo();
procInfo.CreateNoWindow = true;
procInfo.UseShellExecute = true;
procInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procInfo;
proc.EnableRaisingEvents = true;
proc.Exited += new EventHandler(proc_Exited);
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
proc.Start(...)
// Do something with proc.Handle...
void  proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
   /* Do something here... */
}

void  proc_Exited(object sender, EventArgs e)
{
/* Do something here... */
}

Редактировать: Я изменил код, чтобы показать средства сбора и обработки событий, а также я показал использование свойства Handle, которое является дескриптором запущенного процесса .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...