У меня есть веб-приложение ASP.NET, работающее в IIS. Пул приложений и веб-приложение настроены на запуск как пользователь, которого я создал (не NETWORKSERVICE). У этого пользователя есть все необходимые разрешения (например, псевдо-администратор).
Приложение вызывает Process.Start()
с URI магнита. На веб-сервере установлено приложение, которое может автоматически запускать и начинать обработку URI магнита. Если я войду в URI магнита в поле "Выполнить" веб-сервера, все будет работать так, как ожидалось: приложение запускает и начинает обработку URI в фоновом режиме. То же самое происходит, если я отлаживаю приложение из Visual Studio - он работает так, как ожидалось, потому что экземпляр IIS Express также работает в одном сеансе.
Когда я вызываю процесс из своего веб-приложения, когда он в IIS, он не генерирует никаких исключений или ошибок, но не вызывает приложение. Я предполагаю, что это связано с тем, что IIS выполняет приложение из другого сеанса, в котором работает приложение, поэтому приложение не может отвечать на вызов URI, поэтому процесс просто завершается.
Как я могу изменить эту строку кода для работы в том же контексте, что и рабочий стол, чтобы приложение могло нормально реагировать и обрабатывать URI?
Process.Start("magnet:?xt=urn:btih:0123456789ABCDEF");
Если сеанс рабочего стола не существует (например, что пользователь не зашел на сервер), я ожидал бы, чтобы какое-то захватывающее исключение было выбрано так, чтобы на веб-сайте могла отображаться дружественная ошибка.
Код веб-страницы и сервера ASP.NET выполняется в контексте рабочего процесса ASP.NET на веб-сервере. Если вы используете метод "Старт" на веб-странице или сервере ASP.NET, новый процесс выполняется на веб-сервере с ограниченными разрешениями. Процесс не запускается в том же контексте, что и клиентский браузер, и не имеет доступа к рабочему столу пользователя. http://msdn.microsoft.com/de-de/library/e8zac0ca.aspx
Когда вы используете Process.Start в IIS 7+, он начнет новый процесс как услугу в "сеансе 0", и вы не сможете сделать что-либо интерактивное с этим сеансом, даже если вы войдете в ту же учетную запись на сервере. Тем не менее, вы можете увидеть процесс, запущенный в диспетчере задач (Показать процессы от всех пользователей).
Если магнитные ссылки не связаны, вы можете просто передать ссылку на магнит в качестве аргумента
Process.Start("C:\...\Torrent.exe", "magnet:?...")
Если процесс связанного exe не запускается вообще - перенаправить его вывод (пример) и посмотреть, в чем проблема.
В общем, запуск внешнего процесса из веб-приложений не является хорошей идеей, и вы можете рассмотреть либо запланированную задачу, либо службу Windows, которая опросит общий репозиторий хранилища, чтобы узнать, нужно ли запускать пакетное задание и выполнять ваше приложение.
Пример:
Создайте файл.bat со следующим содержимым
FOR /F %%x IN (c:\\magnet.txt) DO START %%x
DEL /F c:\magnet.txt
Создайте запланированную задачу, которая открывает файл.bat, например, каждую минуту
Готово!
Вы можете попробовать создать специальную учетную запись обычного пользователя на своем сервере, а затем использовать
Process.Start(fileName, userName, password, domain)
для запуска вашего процесса под учетными данными пользователя.
Еще одна идея - создать самообслуживаемую службу WCF и запустить ее под учетной записью пользователя на компьютере. Служба WCF запустит приложение "magnet:". Вызовите службу WCF из вашего кода ASP.NET (через localhost
).
Вместо Process.Start() попробуйте использовать CreateProcessWithLogonW. Аналогичный вопрос ответил в SO: Process.Start() под asp.net?