运行 EXE 文件的 ASP.NET

Posted

技术标签:

【中文标题】运行 EXE 文件的 ASP.NET【英文标题】:ASP.NET running an EXE File 【发布时间】:2009-06-24 16:00:40 【问题描述】:

我正在尝试从 ASP.NET 网站运行旧的 .NET 应用程序。在阅读了 web 和 ***(对于类似的问题)之后,我得到了以下代码。 问题是我总是收到错误代码(我使用的是管理员帐户 只是为了测试目的)。如果我手动运行 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 结果变量为空。 不抛出异常 我正在使用带有 IIS 7.0 的 Windows 2008

提前致谢,

埃泽奎尔

【问题讨论】:

忘了补充,我用的是 W2K8 和 IIS7 请说出你得到的“错误代码”。更好的是,通过在捕获 ex 后发布 ex.ToString() 的结果来发布完整的异常,包括所有 InnerException。 另外,编辑你的问题,不要离开 cmets。 你的意思是 ExitCode = -1066598274 吗? 我知道这已经很老了,但是您的代码中有“管理员”拼写错误,不确定它是否会有所作为。 【参考方案1】:

不要这样做。这很脏,不应该从 ASP.NET 中完成

    写一个windows服务 将请求存储在队列中 服务应该轮询队列和进程。如果需要运行exe。建议服务留在不同的服务器上。

不要这样做。这对 Web 服务器来说非常糟糕,而且不可扩展,也很糟糕

不要

不要

不要

【讨论】:

【参考方案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;
                
            
        
    

【讨论】:

【参考方案3】:

如果你使用

proc.StartInfo.RedirectStandardOutput = true;

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

proc.WaitForExit();

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

【讨论】:

【参考方案4】:

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

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

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

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

【参考方案6】:

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

    创建新的 sql server 作业 在工作属性的常规页面中为其命名 在步骤页面中,创建类型为操作系统 (CmdExec) 的新步骤 指定命令并单击确定保存作业参数

可以使用 EXEC msdb.dbo.sp_start_job @jobname 调用新作业,其中@jobname 是 带有您要开始的作业名称的变量。

注意,当这个job启动时,exe的UI会被隐藏,不会显示;但您可以在任务管理器中找到它。

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

【讨论】:

【参考方案7】:

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

此外,运行一个“hello world”程序以查看问题是否与实际创建进程有关,或者进程本身在给定的上下文中运行是否存在问题,这可能具有教育意义。

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

【讨论】:

感谢您的回答,我添加了 loadUserProfile。我还更改了 cmd.exe 的 .exe,但我仍然得到相同的退出代码。还有其他想法吗?【参考方案8】:

使用下面的代码:

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

【讨论】:

解释你所做的事情总是很有趣...只是转储代码要少得多。 我猜代码是自我解释的!! 代码解释了很多,但您仍然应该提及您所做的与主题启动器不同的地方以及您这样做的原因。仅转储代码确实不能完全帮助一个人。

以上是关于运行 EXE 文件的 ASP.NET的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET入门教程(经典)

转载IIS与asp.net管道

kindEditor

KindEditor编辑器

KindEditor

编辑器KindEditor的使用