• ASP.NET调用cmd命令提示符拒绝访问解决方案


      using System.Diagnostics;
    public class CmdHelper
        {
            private static string CmdPath = @"C:WindowsSystem32cmd.exe";
     
            /// <summary>
            /// 执行cmd命令
            /// 多命令请使用批处理命令连接符:
            /// <![CDATA[
            /// &:同时执行两个命令
            /// |:将上一个命令的输出,作为下一个命令的输入
            /// &&:当&&前的命令成功时,才执行&&后的命令
            /// ||:当||前的命令失败时,才执行||后的命令]]>
            /// 其他请百度
            /// </summary>
            /// <param name="cmd"></param>
            /// <param name="output"></param>
            public static void RunCmd(string cmd, out string output)
            {
                cmd = cmd.Trim().TrimEnd('&') + "&exit";//说明:不管命令是否成功均执行exit命令,否则当调用ReadToEnd()方法时,会处于假死状态
                using (Process p = new Process())
                {
                    p.StartInfo.FileName = CmdPath;
                    p.StartInfo.UseShellExecute = false;        //是否使用操作系统shell启动
                    p.StartInfo.RedirectStandardInput = true;   //接受来自调用程序的输入信息
                    p.StartInfo.RedirectStandardOutput = true;  //由调用程序获取输出信息
                    p.StartInfo.RedirectStandardError = true;   //重定向标准错误输出
                    p.StartInfo.CreateNoWindow = true;          //不显示程序窗口
                    p.Start();//启动程序
     
                    //向cmd窗口写入命令
                    p.StandardInput.WriteLine(cmd);
                    p.StandardInput.AutoFlush = true;
     
                    //获取cmd窗口的输出信息
                    output = p.StandardOutput.ReadToEnd();
                    p.WaitForExit();//等待程序执行完退出进程
                    p.Close();
                }
            }
        }


    使用示例

    示例1:显示ipconfig信息
    string cmd =@"ipconfig/all";

    示例2:打开VS2010命令提示      
    string cmd =@"C:&cd C:Program Files (x86)Microsoft Visual Studio 10.0VC&vcvarsall.bat";

    示例3:使用sn.exe工具产生密钥对并显示          
    string cmd =@"C:&cd C:Program Files (x86)Microsoft Visual Studio 10.0VC&vcvarsall.bat&sn -k d:LicBase.snk&sn -p d:LicBase.snk d:LicBasePubKey.snk&sn -tp d:LicBasePubKey.snk";

    调用
    string output = "";
    CmdHelper.RunCmd(cmd, out output);
    MessageBox.Show(output);

    ======================

    最近做关于Windows Server POP3服务器的小项目,翻遍网络,也没能找到接口。

       值得庆幸的是最终发现了一个控制台接口winpop.exe,也就是用cmd命令提示符与POP3服务器交互。

        这样实属无奈之举,用cmd命令效率低不说,而且获取、分析返回信息相当麻烦。然而这还不算什么,最主要的是:B/S模式下,网页程序有权限调用cmd吗?
       这里调用cmd,当然不是调用客户机器上的cmd,而是服务器上的cmd,这样心里还有点底。

       小心翼翼的在我电脑上做了实验,成功在aspx页面中调用cmd,并执行了ping命令,而且顺利获取、分析返回信息。

       于是我满怀信心的把测试程序发布到了服务器上,也是顺利执行!核心代码如下:

    using System.Diagnostics;  
    using System.IO;  
      
        /// <summary>  
    /// cmd命令执行助手类  
    /// </summary>  
    public class CMDHelper  
    {  
        private Process p = null;  
        private StreamReader reader = null;  
      
        /// <summary>  
        /// 通过cmd执行ping命令  
        /// </summary>  
        /// <param name="cmdString">命令内容</param>  
        /// <returns>命令执行结果</returns>  
        public string execute(string cmdString)   
        {  
            ProcessStartInfo start = new ProcessStartInfo("cmd.exe");  
      
            start.FileName = "ping";  
            start.Arguments = cmdString;  
      
            start.CreateNoWindow = true;  
      
            start.RedirectStandardOutput = true;  
      
            start.RedirectStandardInput = true;  
      
            start.UseShellExecute = false;  
      
            start.WorkingDirectory = "C:\WINDOWS\system32";  
      
            p = Process.Start(start);  
      
            reader = p.StandardOutput;  
      
            string line = "";  
            string lineTemp = "";   
      
            //逐行读出返回的数据,并做一定处理,方便解析  
            while (!reader.EndOfStream)  
            {  
                lineTemp = reader.ReadLine();//读出一行  
                //将空行用*号表示  
                if (lineTemp == "")  
                {  
                    line += "*";  
                }  
                else  
                {  
                    line += lineTemp;  
                }  
            }  
      
            return line;  
        }  
    }  

           可是高兴的太早了,当我把start.FileName= "ping";改成start.FileName = "winpop";,也就是执行winpop命令,这时候无情的返回了“拒绝访问”。

             分析一下,是什么拒绝访问了?刚刚已经成功执行了ping,说明访问cmd的权限是有的,执行的ping命令实际上是利用cmd.exe调用了ping.exe,这说明访问ping.exe的权限也是有的。而现在换成winpop命令,却出现了拒绝访问,说明我们没有权限访问winpop.exe!

             这下该怎么办呢?首先想到的就是修改winpop.exe的访问权限,右击winpop.exe(在Windows/System32文件夹下),点击【属性】---【安全】选项卡,在用户中加入当前用户,还是拒绝;加入ASP.NET用户,还是拒绝;最后急了,加上Everyone用户,依然拒绝!看来这种方法没有作用。

             再冷静的分析一下,这肯定是权限问题引起的。那么这个权限究竟在哪限制了?

    别忘了,我们的程序是运行在IIS中的,所有的生杀大权,都由IIS掌握,权限是不是在这里呢?

             果断google一下,IIS还真有权限,更确切的说,是IIS中的“应用程序池”可以设置权限。接下来就说说如何设置。

             先从IIS中找到你的网站,在右键--【属性】中看看使用的应用程序池是哪个,然后【在应用程序池】目录下找到它,右键---【属性】

             找到【标识】选项卡,再找到【预定义账户】,在后边的下拉菜单中选择“本地系统”就可以了!

             这样一来,你的网站就可以随心所欲的执行cmd命令了,其实不仅仅是执行cmd命令,简直是至高无上的权限!

             提醒一下,这样更改的是应用程序池权限,因此所有使用这个应用程序池的网站都有很高的权限,这是相当危险的,还须谨慎使用!!

             作为完整的解决方案,还需要提一点。

             调用cmd执行命令时,可以指定用户(用户是指系统用户,也就是登录电脑时用的帐号密码),这样也可以获得一定的权限。代码如下:

    using System.Diagnostics;  
    using System.IO;  
      
    /// <summary>  
    /// cmd命令执行助手类  
    /// </summary>  
    public class CMDHelper  
    {  
        private Process p = null;  
        private StreamReader reader = null;  
      
        /// <summary>  
        /// 通过cmd执行ping命令  
        /// </summary>  
        /// <param name="cmdString">命令内容</param>  
        /// <returns>命令执行结果</returns>  
        public string execute(string cmdString)   
        {  
            ProcessStartInfo start = new ProcessStartInfo("cmd.exe");  
      
            start.FileName = "ping";  
            start.Arguments = cmdString;  
      
            start.CreateNoWindow = true;  
      
            start.RedirectStandardOutput = true;  
      
            start.RedirectStandardInput = true;  
      
            start.UseShellExecute = false;  
      
            start.WorkingDirectory = "C:\WINDOWS\system32";  
              
            start.UserName = "administrator"; //指定用户  
            //构造用户密码,假定密码为123,必须一个字符一个字符的添加  
            System.Security.SecureString password = new System.Security.SecureString();  
            password.AppendChar('1');  
            password.AppendChar('2');  
            password.AppendChar('3');  
            start.Password = password;  
              
            p = Process.Start(start);  
      
            reader = p.StandardOutput;  
      
            string line = "";  
            string lineTemp = "";   
      
            //逐行读出返回的数据,并做一定处理,方便解析  
            while (!reader.EndOfStream)  
            {  
                lineTemp = reader.ReadLine();//读出一行  
                //将空行用*号表示  
                if (lineTemp == "")  
                {  
                    line += "*";  
                }  
                else  
                {  
                    line += lineTemp;  
                }  
            }  
      
            return line;  
        }  
    }  

       但是本人在Windows Server2003下测试失败,只要指定用户,网页程序就挂起,直到响应超时,原因未知。

  • 相关阅读:
    存储过程
    数据库中的锁
    数据库事务
    三大范式
    IOC(一)
    rabbitmq部署
    配置SQLServer2012,允许远程连接
    6种常见的Git错误以及解决的办法
    灵活使用Win+R快捷键提高工作效率
    sql 创建视图常用的几种sql函数
  • 原文地址:https://www.cnblogs.com/hnsongbiao/p/7440034.html
Copyright © 2020-2023  润新知