Это происходит, если вы пытаетесь запустить mstsc из 32-битного приложения в 64-битной Windows.
(Источник: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/22c10140-a502-4aa1-98d3-3607b8b573e8/)
Есть две версии mstsc в 64-битной Windows:
c:\windows\system32\mstsc.exe
- это 64-битная версия c:\windows\syswow64\mstsc.exe
-более или менее «перенаправление», которое откроет c:\windows\system32\mstsc.exe
из процесса, отличного от вашего приложения.
У меня возникла та же проблема. Мое приложение запустило mstsc, процесс немедленно завершился и mstscвновь появился с другим родительским процессом и другим PID.
Это происходит потому, что 64-разрядная Windows использует перенаправление файловой системы для перенаправления вызовов на 64-разрядные c:\windows\system32
исполняемые файлы на c:\windows\syswow64
.
Существует два решения:
- Перекомпилируйте ваше приложение в 64-битное. Тогда ваше приложение также будет использовать 64-битный mstsc.
- Отключить перенаправление файловой системы (см. http://blog.tonycamilli.com/2005/07/disabling-wow64-file-system.html) и получить доступ к 64-битному mstsc из вашего 32-битного приложения.
Я только попробовал перекомпилировать, и это сработало.: -)
Редактировать: Если вы не хотите, чтобы ваши пользователи использовали правильную версию (мы используем развертывание ClickOnce, поэтому мы скорее отправим one ссылка на всех), вот обходной путь:
Если вы используете файл .RDP для mstsc, просто добавьте уникальный токен к имени вашего файла.mstsc будет запущен из командной строки, например mstsc host_user_token.rdp
.
Теперь, после того, как вы позвонили Process.Start
, выполните Process.WaitForExit
с коротким тайм-аутом (5 с).Если процесс не завершился, у вас есть нужный объект.
Если процесс did завершился, выполните небольшой цикл опроса (интервал 100 мс, время ожидания 5 с), который проверяет процессы с помощью вашего токена.:
var timeout = AppSettings.GetIntValue(
Constants.SettingsKeyProcessFinderTimeout, Constants.ProcessFinderTimeoutDefault);
int elapsedTime = 0;
Process process = null;
while (elapsedTime <= timeout)
{
process =
Process.GetProcessesByName("mstsc").FirstOrDefault(p => p.StartInfo.Arguments.Contains(guid));
Logger.TraceVerbose(
string.Format(
"Elapsed time: {0}; Found process with PID {1}", elapsedTime, process == null ? -1 : process.Id));
if (process != null)
{
break;
}
Thread.Sleep(SleepInterval);
elapsedTime += SleepInterval;
}
После этого цикла, если у вас все еще есть process == null
, произошла какая-то ошибка (процесс не был найден или никогда не выполнялся вообще).Если у вас есть ссылка на процесс, это «новый» процесс mstsc.