ASP.NET运行EXE文件

时间:2009-06-24 16:00:40

标签: c# .net process execution

我正在尝试从ASP.NET网站运行旧的.NET应用程序。在阅读了Web和Stackoverflow之后(针对类似的问题),我来看下面的代码。 问题是我总是得到一个错误代码(我使用的是管理员帐户 只是为了测试目的)。如果我手动运行exe它可以正常工作。

private void Execute(string sPath)
{
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo.UserName = "administrador";
    string pass = ".............";

    System.Security.SecureString secret = new System.Security.SecureString();
    foreach (char c in pass) secret.AppendChar(c);

    proc.StartInfo.Password = secret;
    proc.StartInfo.WorkingDirectory = ConfigurationManager.AppSettings["WORKINGDIRECTORY"].ToString();
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.FileName = sPath;
    proc.Start();
    proc.WaitForExit();
    string result = proc.StandardOutput.ReadToEnd();
    Response.Write(result + " - "  + proc.ExitCode);
    proc.Close();
}

}

我得到的exitcode是:-1066598274 结果变量为空。 没有异常被抛出 我正在使用Windows 2008与IIS 7.0

提前致谢,

Ezequiel

8 个答案:

答案 0 :(得分:4)

不要这样做。这很简单,不应该从ASP.NET

完成
  1. 编写Windows服务
  2. 将请求存储在队列中
  3. 服务应轮询队列和进程。如果需要运行exe。建议该服务保留在不同的服务器中。
  4. 不要这样做。这非常糟糕,不可扩展,对Web服务器不好

    不要

    不要

    不要

答案 1 :(得分:2)

    protected void btnSubmit_Click(object sender, System.EventArgs e)
    {
        if (Page.IsValid)
        {
            litMessage.Visible = true;

            System.Diagnostics.Process oProcess = null;

            try
            {
                string strRootRelativePathName = "~/Application.exe";

                string strPathName =
                    Server.MapPath(strRootRelativePathName);

                if (System.IO.File.Exists(strPathName) == false)
                {
                    litMessage.Text = "Error: File Not Found!";
                }
                else
                {
                    oProcess =
                        new System.Diagnostics.Process();

                    oProcess.StartInfo.Arguments = "args";

                    oProcess.StartInfo.FileName = strPathName;

                    oProcess.Start();

                    oProcess.WaitForExit();

                    System.Threading.Thread.Sleep(20000);

                    litMessage.Text = "Application Executed Successfully...";
                }
            }
            catch (System.Exception ex)
            {
                litMessage.Text =
                    string.Format("Error: {0}", ex.Message);
            }
            finally
            {
                if (oProcess != null)
                {
                    oProcess.Close();
                    oProcess.Dispose();
                    oProcess = null;
                }
            }
        }
    }

答案 2 :(得分:1)

如果您使用

proc.StartInfo.RedirectStandardOutput = true;

然后你必须在进程执行时读取流,而不是在调用

之前
proc.WaitForExit();

标准错误流也是如此。有关详细信息,请参阅MSDN文档。

答案 3 :(得分:1)

您需要在最后重新排序输出读数。

它希望你在waitforexit()调用之前阅读,所以你应该:

proc.Start();
string result = proc.StandardOutput.ReadToEnd();
Response.Write(result + " - "  + proc.ExitCode);
proc.WaitForExit();
proc.Close();

答案 4 :(得分:1)

如果您尝试运行的应用程序实际上是一个.NET应用程序,您可能根本不需要在单独的进程中运行它。相反,您可以利用.NET可执行文件也是程序集的事实。我不认为Visual Studio会让你引用以.exe结尾的程序集,但命令行编译器会。

我会尝试使用命令行编译器创建一个简单引用可执行程序集的包装程序集,并直接调用其Main()方法,传入您通常会指定的任何命令行参数的字符串数组。退出代码(如果有)将是Main方法的整数返回值。然后,您只需从ASP.NET应用程序中调用包装程序集即可。

根据可执行文件的功能以及它与控制台的交互程度,这种方法可能根本不起作用。但如果它适用于您的情况,它应该比启动单独的流程要好得多。

答案 5 :(得分:1)

我所做的是让ms sql作业调用可执行文件。 可执行文件将作为SQL Server代理服务帐户运行。

  1. 创建新的sql server作业
  2. 在作业属性的常规页面中为其命名
  3. 在步骤页面中,创建操作系统类型(CmdExec)
  4. 的新步骤
  5. 说明命令并单击“确定”以保存作业参数
  6. 可以使用EXEC msdb.dbo.sp_start_job @jobname调用新作业,其中@jobname是 带有你想要开始的工作名称的变量。

    请注意,当此作业启动时,exe的UI将被隐藏,不会显示;但你可以在任务管理器中找到它。

    我在几个应用程序中使用了这种方法,尤其是在网页上无法完成的耗时操作。

答案 6 :(得分:0)

您可能需要将proc.StartInfo.LoadUserProfile属性设置为true,以便将管理员的用户配置文件内容加载到注册表中(默认情况下不会发生AFAIK)。

此外,运行“hello world”程序以查看问题是否通过动态创建流程或者流程本身是否在给定的上下文中运行时可能具有教育意义。

最后,作为尝试缩小问题可能范围的一个步骤,您可能希望使用管理员或系统凭据运行ASP.NET进程本身,以查看帐户权限中的某些内容是否为ASP.NET实例正在运行是问题的一部分(但请仅在故障排除时执行此操作)。

答案 7 :(得分:0)

使用以下代码:

    ProcessStartInfo info = new ProcessStartInfo("D:\\My\\notepad.exe");
    info.UseShellExecute = false;
    info.RedirectStandardInput = true;
    info.RedirectStandardError = true;
    info.RedirectStandardOutput = true;
    //info.UserName = dialog.User;   
    info.UserName = "xyz";
    string pass = "xyz";
    System.Security.SecureString secret = new System.Security.SecureString();
    foreach (char c in pass)
        secret.AppendChar(c);
    info.Password = secret;
    using (Process install = Process.Start(info))
    {
        string output = install.StandardOutput.ReadToEnd();
        install.WaitForExit();
        // Do something with you output data          
        Console.WriteLine(output);
    }