从 ASP.NET 启动进程 - 为啥进程会立即终止?
Posted
技术标签:
【中文标题】从 ASP.NET 启动进程 - 为啥进程会立即终止?【英文标题】:Starting a process from ASP.NET - Why does the process immediately die?从 ASP.NET 启动进程 - 为什么进程会立即终止? 【发布时间】:2011-11-09 06:50:23 【问题描述】:我正在尝试从 ASP.NET C# 应用程序启动进程。我的应用程序通过进程自己的 API(这是第三方程序)与该进程通信。我只需要在某些情况下运行这个进程,所以我认为没有必要让它在服务器上持续运行,因此需要从我的应用程序启动进程。
我正在使用的进程设置为通过命令行参数以“不露面”模式运行,因此不需要在任何地方出现 GUI。在不提供太多信息的情况下,它对特定数据执行复杂的计算(数据从流程内部的外部源中提取,并且此数据不断更新)并通过 API 公开结果。我的应用程序通过传递 xml 格式的查询并接收类似格式的响应与此 API 进行通信。
我遇到的问题是启动进程工作正常,但它以 SYSTEM 用户身份运行进程。这是一个问题,因为我正在启动的进程已注册给特定用户,并且在以 SYSTEM 身份运行时以有限的“试用版”模式运行,而我需要的 API 无法按预期工作。因此,我打算以注册程序的特定用户身份运行。但是,当我为正确的用户添加登录信息时,该过程开始并立即退出... 有什么具体的方法我应该这样做吗?
以下是我无法正常工作的代码:
public static bool ProcessActive()
return Process.GetProcesses().Any(p => p.ProcessName.Equals("Process", StringComparison.InvariantCultureIgnoreCase));
public static void StopProcess()
List<Process> processExists = Process.GetProcesses().Where(p => p.ProcessName.Equals("Process", StringComparison.InvariantCultureIgnoreCase)).ToList();
foreach (Process p in processExists)
p.Kill();
public static bool StartProcess(bool stopIfStarted = false)
bool retVal = false;
using (System.Security.SecureString password = new System.Security.SecureString())
// Set up the variables required to run the process
ProcessStartInfo pInfo = new ProcessStartInfo(@"C:\Program Files\Program\Program.exe");
pInfo.Arguments = @"-arg1 -arg2";
pInfo.WorkingDirectory = @"C:\Program Files\Program";
pInfo.UserName = "username";
pInfo.Domain = "DOMAIN";
password.AppendChar('p');
/* repeat for other password chars */
pInfo.Password = password;
pInfo.UseShellExecute = false;
if (System.IO.File.Exists(pInfo.FileName))
//Check if the process is already running
bool processExists = ProcessActive();
if (stopIfStarted && processExists)
StopProcess();
processExists = ProcessActive();
//if not, start it.
if (!processExists)
StatusHelper.Log("Process isn't running. Starting process...");
using (Process realProcess = Process.Start(pInfo))
processExists = ProcessActive();
System.Threading.Thread.Sleep(1000);
processExists = ProcessActive();
if (realProcess.HasExited)
// Always gets here
retVal = processExists;
return retVal;
【问题讨论】:
你根本不应该从 ASP.NET 启动进程......因为 Vista MS 已经非常严格的安全性,所以 Windows 服务(IIS/ASP.NET 在这方面只是一个特殊的子类型)被限制做任何“类似桌面”的事情......请详细说明这是什么类型的过程(控制台或用户界面?它到底做了什么?等等)。 我在我的问题中添加了更多说明。该过程以一种“匿名”模式运行,没有 UI 和控制台输出。我通过基于 xml 的 API 与这个进程进行通信。 【参考方案1】:我从 ASP .Net 4.0 开始进程的方法: 1. 实际启动进程的远程类(它在命令行中启动 Adobe Reader 以打印 PDF) 2. 系统托盘应用程序作为远程对象的主机 3. 在 .Net 2.0 和特定用户下运行的 Web 服务,作为远程对象的客户端 4. ASP .Net 4.0网站调用webservice方法
当一个进程从 ASP .Net 启动时,它“挂起”。我可以在任务管理器中看到它,但它什么也没做,所以这是我找到的唯一解决方案。您可以在控制台应用程序或 Windows 服务中托管远程对象。 WCF 将是另一个不错的远程处理选择,但我还没有尝试过。
【讨论】:
【参考方案2】:它可能无法回答您的问题,但做这类事情的一种相当稳健的方式是,例如安装了使用正确凭据运行的 Windows 服务,并在 Web 服务器和服务之间进行一些通信,例如通过私人消息队列甚至一些 Web API。
这样,您就不会因为授予 Web 进程比它真正需要的更多的权利而使您的计算机陷入危险境地。
您可以想象,如果您在 Web 进程中所做的事情是可能的,那么攻击就有很多可能在机器上获得提升的权限。
【讨论】:
【参考方案3】:我不知道设置进程用户权限的任何具体方法,但是您可以查看立即退出的原因是否在进程本身内部,例如由于权限受限而引发异常。
使用 StartInfo 获取流程输出流:
pInfo.StartInfo.RedirectStandardInput = true;
pInfo.StartInfo.RedirectStandardOutput = true;
pInfo.StartInfo.RedirectStandardError = true;
pInfo.StartInfo.ErrorDialog = false;
开始该过程后,您可以这样阅读:
StreamReader sOut = pInfo.StandardOutput;
StreamReader sError = pInfo.StandardError;
string standardResult = sOut.ReadToEnd();
string standardError = sError.ReadToEnd();
【讨论】:
我实际上尝试过并将结果记录到一个文件中,但没有任何输出......不过感谢您的建议。以上是关于从 ASP.NET 启动进程 - 为啥进程会立即终止?的主要内容,如果未能解决你的问题,请参考以下文章