繁体   English   中英

运行EXE文件的ASP.NET

[英]ASP.NET running an EXE File

我正在尝试从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();
}

}

我得到的退出代码是:-1066598274结果变量为空。 我将Windows 2008与IIS 7.0一起使用时不会引发异常

提前致谢,

埃泽奎尔

不要这样 这只是普通的脏话,不应在ASP.NET中完成

  1. 编写Windows服务
  2. 将请求存储在队列中
  3. 该服务应轮询队列和进程。 如果需要,请运行exe。 建议该服务位于其他服务器上。

不要这样 这非常糟糕,无法扩展,对Web服务器不利

    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;
                }
            }
        }
    }

如果您使用

proc.StartInfo.RedirectStandardOutput = true;

那么您必须在流程执行时读取流,而不是在调用之前

proc.WaitForExit();

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

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

它希望您在waitforexit()调用之前先阅读,因此您应该具有:


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

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

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

根据可执行文件的功能以及与控制台的交互程度,此方法可能根本不起作用。 但是,如果它确实适合您的情况,则它的性能应该比分解一个单独的过程好得多。

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

  1. 创建一个新的SQL Server作业
  2. 在作业属性的常规页面上为其命名
  3. 在“步骤”页面中,创建“操作系统(CmdExec)”类型的新步骤
  4. Speeify命令,然后单击“确定”以保存作业参数

可以使用EXEC msdb.dbo.sp_start_job @jobname调用新作业,其中@jobname是携带要启动的作业名称的变量。

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

我已经在一些应用程序中采用了这种方法,特别是耗时的操作,这些操作无法在网页上完成。

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

另外,运行“ hello world”程序以查看问题是否在于实际创建流程,或者流程本身在给出的上下文中运行是否存在问题,这可能是有教益的。

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

使用以下代码:

    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);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM