Appcmd.exe的和DNSCMD.EXE返回StandardOutput时表现不同 [英] appcmd.exe and dnscmd.exe behaving different when returning StandardOutput

查看:352
本文介绍了Appcmd.exe的和DNSCMD.EXE返回StandardOutput时表现不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我'开发一些东西,应该像一个自我部署的应用程序托管面板。我创建了具有文件名和参数作为参数,并在执行时应该给面板网页上输出的方法。

下面是我的方法;

 私人字符串ExecuteCmd(字符串SYSUSER,SecureString的SecureString的,字符串参数,字符串文件名)
    {
        使用(进程p =新工艺())
        {
            p.StartInfo.FileName =文件名;
            p.StartInfo.UseShellExecute = FALSE;
            p.StartInfo.CreateNoWindow = TRUE;
            p.StartInfo.RedirectStandardError = TRUE;
            p.StartInfo.RedirectStandardOutput = TRUE;            p.StartInfo.UserName = SYSUSER;
            p.StartInfo.Password = SecureString的;            p.StartInfo.Arguments =参数;
            p.Start();
            p.WaitForExit();            StreamReader的SR = p.StandardOutput;            p.Close();            字符串消息= sr.ReadToEnd();            返回消息;
        }
    }

当我用这个方法来创建IIS站点(与Appcmd.exe的)我得到我上执行命令PROMT这个可执行文件的所有输出。但是,当涉及到DNSCMD.EXE在DNS中创建条目,我什么也没得到! StandardOutput刚出来空。我使用管理员凭据来执行这些可执行文件。顺便说一句,我是在Windows Server 2012上的斯坦达特。我没有测试Server 2008上的这种方法尚未R2,但我相信结果会是一样的,反正。

这是一种奇怪的,我看到APPCMD和DNSCMD可执行文件的行为不同的方法相同。

它是什么,我在这里丢失?

谢谢!

编辑:无论StandardOutput和StandardError的是为DNSCMD.EXE返回错误

EDIT2:我改的ReadLine()来为ReadToEnd()。那是什么,当我打转转,想事情,我变了。原来的code的ReadToEnd的()。

EDIT3:完整的方法文件路径和参数。
这是IIS,这表明没有任何问题的输出;

 私人字符串ExecuteAppCmd​​(字符串SYSUSER,SecureString的SecureString的)
    {
        使用(进程p =新工艺())
        {
            p.StartInfo.FileName = @C:\\ WINDOWS \\ SYSTEM32 \\ INETSRV \\ Appcmd.exe的;
            p.StartInfo.UseShellExecute = FALSE;
            p.StartInfo.CreateNoWindow = TRUE;
            p.StartInfo.RedirectStandardError = TRUE;
            p.StartInfo.RedirectStandardInput = TRUE;
            p.StartInfo.RedirectStandardOutput = TRUE;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;            p.StartInfo.UserName = SYSUSER;
            p.StartInfo.Password = SecureString的;            p.StartInfo.Arguments =排行榜网站domain.com
            p.Start();
            p.WaitForExit();            StreamReader的SR = p.StandardOutput;            p.Close();            。字符串消息= sr.ReadToEnd()更换(\\ n,< BR />中);            返回消息;
        }
    }

APPCMD列表网站domain.com显示了在命令PROMT domain.com IIS站点配置。如果do​​main.com不是在IIS中,它显示了一个错误。无论哪种方式,有输出,它工作正常与此code。

这是DNSCMD。这其中确实asp.net页面上的工作,但不显示它与StandardOutput输出。但是,输出显示在命令提示符。

 私人字符串ExecuteDnsCmd(字符串SYSUSER,SecureString的SecureString的)
    {
        使用(进程p =新工艺())
        {
            p.StartInfo.FileName = @C:\\ WINDOWS \\ SYSTEM32 \\ DNSCMD.EXE
            p.StartInfo.UseShellExecute = FALSE;
            p.StartInfo.CreateNoWindow = TRUE;
            p.StartInfo.RedirectStandardError = TRUE;
            p.StartInfo.RedirectStandardInput = TRUE;
            p.StartInfo.RedirectStandardOutput = TRUE;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;            p.StartInfo.UserName = SYSUSER;
            p.StartInfo.Password = SecureString的;            p.StartInfo.Arguments =/ zoneadd domain.com /主;
            p.Start();
            p.WaitForExit();            StreamReader的SR = p.StandardError;            p.Close();            。字符串消息= sr.ReadToEnd()更换(\\ n,< BR />中);            返回消息;
        }
    }


解决方案

我没有一个框,我可以运行DNSCMD.EXE而是因为你声称一切的作品,我只能想象的错误和输出的处理流得到某种程度上纠结起来。如果你试试这个code,唯一性差异的是,这个code在单独的线程处理错误和输出流,并在运行过程中收集他们的输出。如果一切正常,你的code应罚款为好。

  //因为不会有一个输入流,所以不要重定向
        p.StartInfo.RedirectStandardInput = FALSE;        //使用StringBuilder来捕捉一切
        VAR SB =新的StringBuilder();
        //提高对输出和错误事件,并处理它们
        p.EnableRaisingEvents = TRUE;
        p.OutputDataReceived + =(发件人,参数)=> sb.AppendFormat(出:{0}< BR />\",args.Data);
        p.ErrorDataReceived + =(发件人,参数)=> sb.AppendFormat(错误:{0}< BR />\",args.Data);        p.Start();        //启动消费
        p.BeginOutputReadLine();
        p.BeginErrorReadLine();        //等待进程退出
        p.WaitForExit();        p.Close();        //获得了StringBuilder的价值
        字符串消息= sb.ToString();        返回消息;

I'am developing something which should work like a hosting panel for a self deploying application. I created a method which has file name and arguments as parameters and should give the output on the panel web page when executed.

Here is my method;

private string ExecuteCmd(string sysUser, SecureString secureString, string argument, string fileName)
    {
        using (Process p = new Process())
        {
            p.StartInfo.FileName = fileName;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.UserName = sysUser;
            p.StartInfo.Password = secureString;

            p.StartInfo.Arguments = argument;
            p.Start();
            p.WaitForExit();

            StreamReader sr = p.StandardOutput;

            p.Close();

            string message = sr.ReadToEnd();

            return message;
        }
    }

When I use this method to create sites on IIS (with appcmd.exe) I get all the output as I execute this executable on command promt. But when it comes to dnscmd.exe to create entries on DNS, I get nothing! StandardOutput just comes out empty. I use administrator credentials to execute these executables. By the way, I am on Windows Server 2012 Standart. I didn't test this method on Server 2008 R2 yet, but I believe the result would be the same, anyway.

It's kind of strange for me to see appcmd and dnscmd executables behave differently on the same method.

What is it I am missing here?

Thanks!

Edit: Both StandardOutput and StandardError are returning error for dnscmd.exe.

Edit2: I changed ReadLine() to ReadToEnd(). That was something I changed when I was playing around, trying things. The original code had ReadToEnd().

Edit3: Full methods with filepath and arguments. That is for IIS, which shows output with no problems;

private string ExecuteAppCmd(string sysUser, SecureString secureString)
    {
        using (Process p = new Process())
        {
            p.StartInfo.FileName = @"C:\Windows\System32\inetsrv\APPCMD.EXE";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            p.StartInfo.UserName = sysUser;
            p.StartInfo.Password = secureString;

            p.StartInfo.Arguments = " list site domain.com";
            p.Start();
            p.WaitForExit();

            StreamReader sr = p.StandardOutput;

            p.Close();

            string message = sr.ReadToEnd().Replace("\n", "<br />");

            return message;
        }
    }

"appcmd list site domain.com" shows the iis site configuration for domain.com on the command promt. If the domain.com is not in iis, it shows an error. Either way, there is an output and it works fine with this code.

And this is for dnscmd. This one does the job on asp.net page, but does not show it's output with StandardOutput. However, the output is shown on command prompt.

private string ExecuteDnsCmd(string sysUser, SecureString secureString)
    {
        using (Process p = new Process())
        {
            p.StartInfo.FileName = @"C:\Windows\System32\DNSCMD.EXE";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            p.StartInfo.UserName = sysUser;
            p.StartInfo.Password = secureString;

            p.StartInfo.Arguments = " /zoneadd domain.com /primary";
            p.Start();
            p.WaitForExit();

            StreamReader sr = p.StandardError;

            p.Close();

            string message = sr.ReadToEnd().Replace("\n", "<br />");

            return message;
        }
    }

解决方案

I don't have a box where I can run dnscmd.exe but because you claim everything else works, I can only imagine the handling of the error and output streams get somehow tangled up. If you try this code, the only diference is that this code handles both error and output streams on separate threads and collect their output during the run. If this works, your code should be fine as well.

        // as there will not be an input stream so don't Redirect 
        p.StartInfo.RedirectStandardInput = false;

        // use a stringbuilder to capture everything
        var sb = new StringBuilder();
        // raise events on stdout and stderr and handle them
        p.EnableRaisingEvents = true;
        p.OutputDataReceived += (sender, args) => sb.AppendFormat("Out: {0}<br />",args.Data);
        p.ErrorDataReceived  += (sender, args) => sb.AppendFormat("Err: {0}<br />",args.Data);

        p.Start();

        // start consuming
        p.BeginOutputReadLine();
        p.BeginErrorReadLine();

        // wait for process to exit
        p.WaitForExit();

        p.Close();

        // obtain out stringbuilder value
        string message = sb.ToString();

        return message;

这篇关于Appcmd.exe的和DNSCMD.EXE返回StandardOutput时表现不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆