C# 从ASP.NET启动进程-为什么进程会立即停止?

C# 从ASP.NET启动进程-为什么进程会立即停止?,c#,asp.net,process,C#,Asp.net,Process,我正试图从ASP.NET C#应用程序启动一个进程。我的应用程序通过进程自己的API(这是第三方程序)与该进程通信。我只需要在某些情况下运行这个进程,因此我认为没有必要让它一直在服务器上运行,因此需要从我的应用程序启动这个进程 我使用的进程被设置为通过命令行参数以“无面”模式运行,因此不需要GUI显示在任何地方。在不透露太多信息的情况下,它对特定数据执行复杂的计算(数据从流程内的外部源提取,并且该数据不断更新),并通过API公开结果。我的应用程序通过传递xml格式的查询和接收类似格式的响应来与此

我正试图从ASP.NET C#应用程序启动一个进程。我的应用程序通过进程自己的API(这是第三方程序)与该进程通信。我只需要在某些情况下运行这个进程,因此我认为没有必要让它一直在服务器上运行,因此需要从我的应用程序启动这个进程

我使用的进程被设置为通过命令行参数以“无面”模式运行,因此不需要GUI显示在任何地方。在不透露太多信息的情况下,它对特定数据执行复杂的计算(数据从流程内的外部源提取,并且该数据不断更新),并通过API公开结果。我的应用程序通过传递xml格式的查询和接收类似格式的响应来与此API通信

我遇到的问题是,启动该进程工作正常,但它以系统用户的身份运行该进程。这是一个问题,因为我启动的进程是注册给特定用户的,当作为系统运行时,它以有限的“试用版”模式运行,并且我需要的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;
}
publicstaticboolprocessactive(){
返回Process.getProcesss().Any(p=>p.ProcessName.Equals(“Process”,StringComparison.InvariantCultureIgnoreCase));
}
公共静态void StopProcess(){
List processExists=Process.getprocesss().Where(p=>p.ProcessName.Equals(“Process”,StringComparison.InvariantCultureIgnoreCase)).ToList();
foreach(processExists中的进程p){
p、 杀死();
}
}
公共静态bool StartProcess(bool stopIfStarted=false){
bool-retVal=false;
使用(System.Security.SecureString password=new System.Security.SecureString()){
//设置运行流程所需的变量
ProcessStartInfo pInfo=新的ProcessStartInfo(@“C:\Program Files\Program\Program.exe”);
参数=@“-arg1-arg2”;
pInfo.WorkingDirectory=@“C:\Program Files\Program”;
pInfo.UserName=“UserName”;
pInfo.Domain=“Domain”;
password.AppendChar('p');
/*对其他密码字符重复此操作*/
pInfo.Password=密码;
pInfo.UseShellExecute=false;
if(System.IO.File.Exists(pInfo.FileName)){
//检查进程是否已在运行
bool processExists=ProcessActive();
if(stopIfStarted&&processExists){
StopProcess();
processExists=ProcessActive();
}
//如果没有,就开始吧。
如果(!processExists){
StatusHelper.Log(“进程未运行。正在启动进程…”);
使用(Process realProcess=Process.Start(pInfo)){
processExists=ProcessActive();
系统线程线程睡眠(1000);
processExists=ProcessActive();
if(realProcess.HasExited){
//总是来这里
}
retVal=processExists;
}
}
}
}
返回返回;
}

我不知道设置流程用户权限的任何具体方法,但您可以看到立即退出的原因是否在流程本身,比如由于权限有限而引发异常

使用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 4.0启动进程的方法:
1.实际启动进程的远程类(它在命令行中启动Adobe Reader以打印PDF)
2.作为远程对象主机的systray应用程序
3.在.Net 2.0和特定用户下运行的Web服务,作为远程对象的客户端
4.ASP.NET4.0网站调用webservice方法


从ASP.Net启动进程时,它会“挂起”。我可以在任务管理器中看到它,但它什么也不做,所以这是我找到的唯一解决方案。您可以在控制台应用程序或windows服务中托管远程对象。WCF将是远程处理的另一个好选择,但我还没有尝试。

它可能无法回答您的问题,但做这类事情的一种相当稳健的方法是,安装一个Windows服务,该服务使用正确的凭据运行,并在web服务器和服务之间进行一些通信,例如通过私有消息队列或甚至一些web API

这样,您就不会让自己陷入这样的境地:您通过赋予web进程超出其实际需要的权限而损害了您的机器


您可以想象,如果您在web进程中所做的事情是可能的,那么攻击就有很大的可能在机器上获得更高的权限。

您根本不应该从ASP.NET启动进程。。。由于Vista MS极度加强了安全性,所以Windows服务(IIS/ASP.NET只是这方面的一个特殊子类型)被限制做任何“类似桌面”的事情。。。请详细说明这是一个什么样的过程(控制台还是UI?它到底做什么?等等)。我在我的问题中补充了一点澄清。该进程以一种“无脸”模式运行,没有UI和控制台输出。我通过一个基于xml的API与这个过程进行通信。我实际上尝试过,并将结果记录到一个文件中,但没有得到任何输出。。。谢谢你的建议。