使用C#调用外部命令重启IIS应用程序池

2009年5月4日

在这里我们通过.net的Process类调用外部命令, 通过重定向输入, 输出获取执行结果.
添加应用using System.Diagnostics;
核心代码如下

                                p.StartInfo.FileName = "cmd.exe";
                                p.StartInfo.UseShellExecute = false;
                                p.StartInfo.RedirectStandardInput = true;
                                p.StartInfo.RedirectStandardOutput = true;
                                p.StartInfo.RedirectStandardError = true;
                                p.StartInfo.CreateNoWindow = true;
                                p.Start();
                                p.StandardInput.WriteLine(_command);
                                p.StandardInput.WriteLine("exit");
                                //string command = "cscript.exe";
                                //p.StartInfo.Arguments = command + " c:\\windows\\system32\\iisapp.vbs /a \"www.xxx.net\" ";
 
                                //p.WaitForExit();
                                string s = p.StandardOutput.ReadToEnd();
                                p.Close();
                                LogEvent(s, LogType.normal);

_command写到配置文件中, 内容是

<add key="Command" value="cscript.exe c:\\windows\\system32\\iisapp.vbs /a www.xxx.net" />

这样就可以简单的实现重新启动指定的应用程序池了.
您可以通过命令iisapp -a来查看当前服务器上的所有应用程序.

最后可以根据自己的需要把这个代码写成windows服务, 安装到服务器上. 既可实现定时重新启动应用程序池功能.

admin CSharp

PHP中单件模式(SingletonPattern)的实现

2009年4月29日

单件(singleton)模式作为设计模式的一个典型而且简单的构造型模式, 已经在很多项目的实际开发中被广泛使用, 单件模式要求一个类有且仅有一个实例,然后提供一个全局的访问点.也就是其所有的相关操作都是基于同一个实例的引用.
单件模式的特点:

  • 单件类只能有一个实例
  • 单件类必须自己创建自己的唯一实例
  • 单件类必须给所有其它对象提供这一实例
  • 单件模式的优点:

  • 从逻辑上来讲, 仅有一个实例保证了逻辑的正确性
  • 通过共享减少的使用
  • 减少应为频繁的构造而带来的应用上的损失
  • 下面通过一个简单的例子来说一些单件模式
    在我们实际的应用中, 大家都知道数据库的连接资源是非常宝贵的, 通过数据库句柄到数据库的连接是独占的,每次的连接和关闭数据库都是一笔非常大的开销, 那么我们如何在应用程序中来共享数据库句柄呢? 我们可以通过单件模式实现.
    以下程序用到三个PHP文件, 程序只是为了展示单件模式,本身不具备任何价值.
    MySQL.php

    class MySQL {
    	private $dbhost = 'localhost';
    	private $dbuser = 'root';
    	private $dbpass = '123';
    	private $db	    = 'test';
     
    	public $guid;
     
    	//======================================
    	// 函数: connect()
    	// 功能: 连接数据库
    	// 返回:
    	//======================================
    	public function __construct()
    	{
    		$this->link_id = mysql_connect($this->dbhost, $this->dbuser, $this->dbpass);
    		$this->guid = md5(uniqid());
    		if (!$this->link_id)
    		{
    			$this->halt("数据库连接失败.请检查连接参数.");
    			return;
    		}
     
    		if (!mysql_select_db($this->db, $this->link_id))
    		{
    			$this->halt("选择数据库".$this->db."失败.");
    			return;
    		}
    		mysql_query("SET NAMES 'utf8'");
    	}
    }

    Singleton.php

    <?php
    class Singleton {
    	private $_db;
    	private static $_single = null;
     
    	public static function getInstance() {
    		if (self::$_single === null)
    			self::$_single = new Singleton();
    		return self::$_single;
    	}
     
    	function __construct() {
    		$this->_db = new MySQL();
    	}
     
    	public function db() {
    		return $this->_db;
    	}
    }
     
    /* End of file */
    /* Location: */

    Test.php

    <?PHP
    require_once ('MySQL.php');
    require_once ('Singleton.php');
    header('content-type:text/html; charset=utf-8');
     
    echo '单件模式____________________________<br />';
    $s1 = Singleton::getInstance()->db();
    $s2 = Singleton::getInstance()->db();
    echo '$s1->guid:'.$s1->guid.'<br />';
    echo '$s1->guid:'.$s2->guid.'<br />';
    echo ($s1 === $s2) ? 'true' : 'false';
    echo '<br />';
     
    echo '直接实例化对象________________________________<br />';
    $d1 = new MySQL();
    echo '$d->guid:'.$d1->guid.'<br />';
    $d2 = new MySQL();
    echo '$d1->guid:'.$d2->guid.'<br />';
    echo ($d1 === $d2) ? 'true' : 'false';
    ?>

    将这三个文件放到一个目录中, 最后浏览test.php,可以看到
    通过单件模式获取的2个对象guid参数任何时候都是相同的,且这两个对象是恒等的.
    而直接实例出来的2个DB对象则刚好相反.
    通过比较, 相信你已经很轻松的掌握了单件模式的特点.

    转载请注明出处:http://www.suiyuan.org

    admin 生活

    The Rose

    2009年4月29日

    The Rose
    by 阿桑
    asang
    Some say love it is a river
    that drowns the tender reed
    some say love it is a razor
    that leaves your soul to bleed
    some say love it is a hunger
    and endless aching need
    i say love it is a flower
    and you its only seed
    it’s the heart afraid of breaking
    that never learns to dance
    it’s the dream afraid of waking
    that never takes the chance
    it’s the one who won’t be taken
    who can not seem to give
    and the soul afraid of dying
    that never learns to live
    when the night has been too lonely
    and the road has been too long
    and you think that love is only
    for the lucky and the strongjust remember in the winter
    far beneath the bitter snow
    lies the seed that with the sun’s love
    in the spring becomes the rose

    阅读全文…

    admin 音乐

    通过C#实现报警续

    2009年4月17日

    前一篇c#蜂鸣报警系列声音函数
    今天要说的是如何实现连续播放报警声音和停止报警.

            #region 报警
            [DllImport("winmm.dll", EntryPoint = "PlaySound")]
            private static extern bool Win32_PlaySound(string pszSound, IntPtr hmod, uint fdwSound);   
     
            /// <summary>
            /// 播放一个wav音频文件
            /// </summary>
            /// <param name="path"></param>
            /// <param name="asynchronous"></param>
            /// <param name="loop"></param>
            /// <param name="doNotStopPlay"></param>
            public static void PlaySound(string path, bool asynchronous, bool loop, bool doNotStopPlay)
            {
                Win32_PlaySound(path, IntPtr.Zero, (uint)((asynchronous ?
              PlaySoundMessage.SND_ASYNC : PlaySoundMessage.SND_SYNC) | (loop ?
              PlaySoundMessage.SND_LOOP : 0) | (doNotStopPlay ?
              PlaySoundMessage.SND_NOSTOP : 0) | PlaySoundMessage.SND_FILENAME));
            }
     
            /// <summary>
            /// 停止播放
            /// </summary> 
            public static void StopSound()
            {
                Win32_PlaySound(null, IntPtr.Zero, 0);
            }
     
            [Flags()]
            internal enum PlaySoundMessage
            {
                SND_SYNC = 0x0000,
                SND_ASYNC = 0x0001,
                SND_LOOP = 0x0008,
                SND_NOSTOP = 0x0010,
                SND_FILENAME = 0x00020000
            }
            #endregion

    当例如遥测水位中测量的水位大于预警水位, 通过PlaySound(”alarm8.wav”, true, true, false)方法实现连续报警, 你还可以同时弹出窗口提醒之类的信息.
    关闭报警通过方法StopSound()实现就可以了.

    admin CSharp

    正确的使用PHP5中的异常处理

    2009年4月16日

    本来想自己写个具体的例子的, 但是太忙了, 又怕转头就忘了, 用的网上的代码.
    应该明白的是PHP5中的异常处理和类是紧密结合在一起的, 在进行异常捕捉前对代码中可能出现的异常情况进行判断, 然后抛出异常.

    <?php 
    // PHP 5 
    require_once('cmd_php5/Command.php'); 
    class CommandManagerException extends Exception{} 
    class IllegalCommandException extends Exception{} 
     
    class CommandManager { 
        private $cmdDir = "cmd_php5"; 
     
        function __construct() { 
            if (!is_dir($this->cmdDir)) { 
                throw new CommandManagerException("directory error: $this->cmdDir"); 
            } 
        } 
     
        function getCommandObject($cmd) { 
            $path = "{$this->cmdDir}/{$cmd}.php"; 
            if (!file_exists($path)) { 
                throw new IllegalCommandException("Cannot find $path"); 
            } 
            require_once $path; 
            if (!class_exists($cmd)) { 
                throw new IllegalCommandException("class $cmd does not exist"); 
            } 
     
            $class = new ReflectionClass($cmd); 
            if (!$class->isSubclassOf(new ReflectionClass('Command'))) { 
                throw new IllegalCommandException("$cmd is not a Command"); 
            } 
            return $class->newInstance(); 
        } 
    } 
    ?>

    当我们的类不能找到正确的command目录时,将抛出一个CommandManagerException异常;当在生成Command对象时产生错误,则getCommandObject()方法将抛出一个IllegalCommandException异常。注意存在多个可能导致抛出IllegalCommandException异常的原因(如未找到文件,或在文件中未找到正确的类)。我们将前两个例子结合起来并为IllegalCommandException提供整型的错误标识常量来代表不同类型的出错原因。
    现在CommandManager类已经具备了处理这多种出错情况的能力,我们可以增加新的catch语句来匹配不同的错误类型。
    代码后半段

    <?php 
    // PHP 5 
    try { 
        $mgr = new CommandManager(); 
        $cmd = $mgr->getCommandObject('realcommand'); 
        $cmd->execute(); 
    } catch (CommandManagerException $e) { 
        die($e->getMessage()); 
    } catch (IllegalCommandException $e) { 
        error_log($e->getMessage()); 
        print "attempting recovery\n"; 
        // perhaps attempt to invoke a default command? 
    } catch (Exception $e) { 
        print "Unexpected exception\n"; 
        die($e->getMessage()); 
    } 
    ?>

    看了代码, 应该明白这里和c#直接try…catch不同的是多了个判断的过程. 为什么在C#中不需要, 很简单, C#底层中已经对这些代码进行封装过了.
    来个c#打开串口的例子

                try
                {
                    if (comPort.IsOpen) comPort.Close();
     
                    comPort.BaudRate = int.Parse(_baudRate);
                    comPort.DataBits = int.Parse(_dataBits);
                    comPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), _stopBits);
                    comPort.Parity = (Parity)Enum.Parse(typeof(Parity), _parity);
                    comPort.PortName = _portName;
                    comPort.Open();
                    if (this.IsBatch)
                        DisplayData(MsgType.Normal, "当前模式:批量传输,正在接收数据..\n");
                    else
                        DisplayData(MsgType.Normal, "当前模式:实时传输,正在接受数据..\n");
                    return true;
                }
                catch (Exception ex)
                {
                    //DisplayData(MsgType.Error, ex.Message);
                    FormUtility.Alert(ex.Message);
                    return false;
                }

    以前对PHP5的异常处理机制了解的不够透彻, 按照C#的方法直接去了才发现还是有不同的. 呵呵, 学习了.

    admin PHP

    PHP中自定错误和异常处理函数

    2009年4月16日

    PHP 函数set_error_handler()的用法

    <?PHP
    function ErrorHandler($errno, $errmsg, $errfile, $errline) {
    	if ($errno == E_USER_ERROR) {
    		$msg = "<strong>Custom Error:</strong>$errmsg<br />\n";
    		$msg .= "File:$errfile<br />\n";
    		$msg .= "Line Number:$errline<br />\n";
    	}
    	echo $msg;
    	// 记录错误信息
    	error_log(date("[Y-m-d H:i:s]")." -[".$_SERVER['REQUEST_URI']."] :".$msg."\n", 3, 'log.txt');
    //	exit(); // 必要时必须终止脚本执行.
    }
     
    // set_error_handler()函数用于让用户自定义错误处理函数
    // set_error_handler(error_function, error_type)
    // error_function 必须, 制定发生错误时运行的函数
    // error_type 可选, 规定不同的错误级别提示的不同信息, 默认是"E_ALL"
    set_error_handler('ErrorHandler');
     
    $foo = 2;
    if ($foo > 1) {
    	// trigger_error()接收一个错误信息和一个常量作为参数, 
    	// 常量为E_USER_ERROR -> a fatal error
    	//		 E_USER_WARNING -> a non-fatal error
    	//		 E_USER_NOTICE -> a report that may not represent an error 
    	trigger_error("A custom error has been trigglered", E_USER_ERROR);
    }
    ?>

    PHP 函数set_exception_handler()的用法

    <?php
    function ExceptionHandler($e) {
    	echo "<strong>Exception:</strong>".$e->getMessage();
    	echo "Stack Trace String:".$e->getTraceAsString();
    }
     
    // set_exception_handler()函数用于让用户自定义异常处理函数
    // set_exception_handler(exception_function)
    // 该函数需要抛出的exception对象最为参数
    // 在这个异常处理程序被执行后, 脚本会停止执行
    set_exception_handler('ExceptionHandler');
     
    throw new Exception('Uncaught Exception occurred');
    ?>

    admin PHP