2013-02-08 4 views
3

При использовании Process.Start для оболочки другого исполняемого файла (а не типа файла), почему он должен возвращать false и не запускать исполняемый файл, а не бросать исключение? Чтобы быть более ясным, в документации упоминается, что return является «истинным, если запущен ресурс процесса, false, если новый ресурс процесса не запущен (например, если существующий процесс используется повторно)». Все объяснения «существующего процесса повторно используются», похоже, предназначены для запуска файлов, которые открываются в существующем экземпляре программы, которая их обрабатывает (например, запускает .jpg, который открывается в существующем экземпляре редактора изображений). Выпущенный в этом контексте исполняемый файл является собственностью и не делает ничего, чтобы предотвратить выполнение новых экземпляров. Отсутствуют записи или другие признаки, которые приложение даже пыталось запустить. Отзыв о том, почему процесс не был запущен, нигде не встречается.Зачем нужно возвращать значение Process.Start false

Следует отметить, что проблема становится более воспроизводимой, тем выше количество исполняемых файлов, запущенных в быстрой последовательности. Такой же код в производственных средах, похоже, не работает, но нагрузка распределяется лучше на многих машинах. В тестовой среде более 100 процессов запускаются быстро на одной машине, и довольно последовательно последние 7-10 являются единственными, которые не запускаются. Процесс управления способен обнаруживать уже запущенные процессы, когда он запускается, и запускает только те, которые в настоящее время не выполняются. Кажется, что он работает правильно, и когда мы делаем полный свежий старт (все 100+ экземпляров проверяются, чтобы их останавливали, а затем мы запускали их) 7 или около того не запускались, но затем мы можем перезапустить процесс управления и те же исполняемые файлы с те же настройки успешно выполняются. Может быть полезно знать, что все запущенные процессы имеют один и тот же исполняемый файл с различными аргументами командной строки. Процесс управления - это служба Windows, порожденные исполняемые файлы - это приложения командной строки, не зависящие от стандартных потоков ввода или вывода.

В процессе устранения этой проблемы, чтобы быть в безопасности, я обеспечил, чтобы поток, запускающий внешние приложения, запускался в однопоточной квартире, потому что ShellExecuteEx может зависеть от этого, хотя я считаю, что теперь эта инфраструктура учитывает это. Я попытался добавить Thread.Sleep задержки между процессами, которые, как представляется, не влияют на количество приложений, которые не запускаются (с различными задержками, предпринятыми с 100 мс до 300 мс, а в последнее время все больше задержка после каждого экземпляра, достигающего 1500 мс или около того).

Возможно, существует максимальное количество дочерних процессов, создаваемых окнами, или, возможно, некоторая ошибка, которая возникает, когда Windows пытается одновременно запускать множество процессов? Я не смог найти разумный ответ , почему выполнение не выполняется. Вот биты, которые запускают сам исполняемый файл (некоторые внутренние отредактированные, но все рамки код нетронутый):

 if (!Path.IsPathRooted(processPath)) 
     { 
      processPath = Path.GetFullPath(Path.Combine(
       Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), 
       processPath)); 
     } 

     ProcessStartInfo psi = 
       new ProcessStartInfo(processPath, args); 
     psi.UseShellExecute = true; 
     psi.CreateNoWindow = true; 

     Trace("Starting {0} {1}", processPath, args); 

     using (Process process = new Process()) 
     { 
      process.StartInfo = psi; 
      bool success = process.Start(); 
      if (!success) 
      { 
       // this is what doesn't make sense 
      } 
     } 

     Trace("Started {0} {1}", processPath, args); 
+0

Разве это не запускается * любой * процесс или какой-либо конкретной один ? –

+0

@MiserableVariable - «В тестовой среде более 100 процессов запускаются быстро на одной машине, и довольно последовательно последние 7-10 являются единственными, которые не запускаются». – JDB

+0

Извините, что раньше не читал. Работает ли повторная попытка? –

ответ

0

Я немного удивлен, что он не бросал Win32Exception. Попробуйте извлечь последнюю ошибку Win32 после сбоя Process.Start(). Вы делаете это с:

var errorCode = Marshal.GetLastWin32Error(); 

Тогда, при условии, что вы получите сообщение об ошибке Win32, найти его на этом сайте:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx

Смежные вопросы