【问题标题】:Why won't "cmd.exe /C command" end when called via Process.Start()?为什么通过 Process.Start() 调用时“cmd.exe /C 命令”不会结束?
【发布时间】:2011-06-17 09:08:22
【问题描述】:

我正在尝试通过 ASP.Net Web 应用程序的命令提示符运行命令。我可以在 Web 服务器上的任务管理器中看到该进程启动,但是该进程只是坐在那里,永远不会退出,也不会运行我指定的命令。

            Process process = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo();

            startInfo.FileName = "cmd.exe";
            startInfo.Arguments = "/C " +command;
            startInfo.UserName = "myuser";
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardOutput = true;
            startInfo.Domain = "mydomain";
            startInfo.CreateNoWindow = true;

            String pass = "mypass";
            System.Security.SecureString secPass = new System.Security.SecureString();

            foreach (char c in pass.ToCharArray())
            {
                secPass.AppendChar(c);
            }
            secPass.MakeReadOnly();

            startInfo.Password = secPass;

            process.StartInfo = startInfo;
            process.Start();
            //output = process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            process.Close();

我尝试过读取和不读取标准输出。

应用程序将在process.WaitForExit(); 上挂起,直到我通过任务管理器终止进程。

【问题讨论】:

  • 如果你尝试读取标准输出,你看过标准输出是什么吗?尝试阅读标准错误;您可能会收到某种错误消息,甚至可能会显示“按任意键继续...”或类似的内容。
  • @GWLlosa,标准输出和标准错误都是空的。我想到了“按任意键...”,所以我尝试将一个字符写入标准输入,但仍然没有。
  • 为什么要通过cmd运行呢?为什么不直接运行呢?
  • 在不同的机器(不是网络服务器)上运行相同的代码,它运行良好。不知道是什么问题。
  • @Petey 这对我来说毫无意义,对不起。祝您工作顺利。

标签: c# process cmd


【解决方案1】:

我认为我们需要了解您实际尝试处理哪些命令才能确定发生了什么。我们还需要知道服务器运行的是什么操作系统。

例如,我确实在您的 cmets 中看到您尝试过“echo test > C:\test.txt” 在 Windows Server 2008(和 Windows 7)下,根目录需要管理员权限才能创建文件。如果这是在 IIS 下执行的,我的猜测是您的 IIS 用户不是管理员,并且您遇到了安全异常。

此外,由于 UAC,许多命令可能需要提升权限。我不记得确切,但我猜如果这些命令被 UAC 捕获,那么进程正在等待 UAC 确认......我相信你无法通过命令行提供。

如果您登录机器​​并直接执行它,则不会看到此类问题...除非您使用工作进程用户帐户登录。

因此,您需要做的第一件事就是弄清楚您要运行的是什么,并查看正在执行工作进程的用户是否甚至可以执行这些操作。安全措施可以保护您,因此请谨慎授予用户额外权限。

它可能在一台机器上运行而不是在另一台机器上运行的原因取决于这些机器正在运行的操作系统以及正在执行命令的用户的配置。

如果我怀疑这确实是一个安全问题,那么您应该在 serverfault.com 上发布一个问题,询问您需要哪些权限集才能在您的工作进程用户下执行各种命令。

您可能会查看机器事件日志,以查看是否有关于该命令的任何警告或错误。有时这样的事情会出现在那里,让您了解更多关于发生了什么的信息。

【讨论】:

  • 哇。我刚刚看到这个问题有多老了......哎呀。
  • 我不介意,感谢您的意见。其实已经忘记了。这是一个权限问题。
【解决方案2】:

一旦传递给 CMD,控制就传递给了 shell。最好像这样添加关闭它:

private void closeSubProcess()
    {
        Process[] currentProcesses = Process.GetProcesses();
        foreach (Process p in currentProcesses)
        {
            string s = p.ProcessName;
            s = s.ToLower();
            if (s.CompareTo("YOURPROGRAMNAMEHERE") == 0)
            {
                p.CloseMainWindow();
                p.Close();
            }
        }
    }

【讨论】:

  • 这可能会导致进程在它完成它应该做的任何事情之前关闭。
  • 没错,你需要创建一个文件或更新一些东西来告诉 .NET 部分它已经完成,然后将其关闭。
【解决方案3】:

我正在调用 cmd.exe 在 Windows 中启动一个节点模块。 npm显然必须先安装,连同我需要的node模块,然后我可以在C#中调用带有args的模块。问题是,cmd.exe 不会关闭,我必须使用 Task Mgr(就像这个问题一样!)。

        //This requires npm, and the module installed by npm...
        ProcessStartInfo psi = new ProcessStartInfo();
        psi.FileName = "cmd.exe";
        psi.WindowStyle = ProcessWindowStyle.Hidden;
        psi.UseShellExecute = true; //closes command window
        psi.Arguments = "/c <nodemodulename>" + file1 + ".txt " + file2 + ".log";
        Process p = Process.Start(psi);
        p.Close();

/c 参数是关闭 cmd.exe 的关键。当我开始时,我已经输入了/K 参数,这让该死的东西保持运行。解决了。希望这可以帮助。 (这很古老,但我们总是忘记)

【讨论】:

  • (我意识到最初的问题有 /c 参数,但我认为无论如何最好提供这个(/K vs /c)。祝你好运。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-10
  • 1970-01-01
  • 1970-01-01
  • 2018-06-04
  • 2011-12-24
  • 1970-01-01
相关资源
最近更新 更多