代码改变世界

开源项目 开发心得 (2) 之 Mail Monitor(邮件监测器) Part II.(技术是怎样实现的)

2004-06-23 20:38  灵感之源  阅读(...)  评论(... 编辑 收藏

Mail Monitor(邮件监测器) 的使命是做一个C#技术应用例子。从今天开始,我将逐个介绍其用到的C#(.NET)技术。

1、序列化
.NET
中要做对象保持很容易,方法也很多,估计大家用的都是XMLSerializer,实际上,还有其它方法,我今天介绍的就是BinaryFormatter。以下是Mail Monitor中的代码,短短10来行代码就实现了保存和获取。核心是BinaryFormatter,它的功能是把对象以二进制的方式格式化,应用Serialize处理完之后便可保存,要反序列化,就先取得原来的二进制数据,再使用Deserialize恢复。关键问题:每个class都要添加[Serializable]属性,如果类型是hashtable或者自定义类型,应该都加上[XmlElement("节点名称", typeof(类型))]属性。


//
保持信息
  private void SaveSettings()
  { 
   try
   {
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new FileStream(_path, FileMode.Create, FileAccess.Write, FileShare.None);
    formatter.Serialize(stream, _settings);
    stream.Close();
   }
   catch {}
  }

//
读取信息

  private void LoadSettings()
  {
   try
   {
    if(File.Exists(_path))
    {
     IFormatter formatter = new BinaryFormatter();
     Stream stream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read);
     _settings = (Settings) formatter.Deserialize(stream);
     stream.Close();
    }
    else
    {
     MessageBox.Show(this,"Configuration file not found. \r\nIt seems that this is the first time you use Mail Monitor, \r\nplease configure it before usage.");
    }
   }
   catch (Exception ex)
   {
    MessageBox.Show(this,ex.Message);
   }
}

 2、多线程
 要实现多线程很容易,大家都知道用以下方法实现:
     Thread _thread=new Thread(new ThreadStart(GetMailInfo));
     _thread.Start();

 问题在于,当需要终止线程(_thread.Abort)的时候,.NET会给出一个线程中止异常,并且该异常给出的对话框无法捕捉,我的解决办法是先_thread.Suspend,在窗口关闭的时候再_thread.Abort就可以了。

3、多窗口操作
 很多时候,我们需要进行多窗口操作,譬如,主窗口-》选项配置-》具体设置,可能要打开多个窗口,而且窗口之间需要传递数据,我的做法是先New一窗口,再传递属性,然后用窗口.ShowDialog,这样就解决了重复打开的问题。

4、注册表
 如果要写注册表,打开OpenSubKey的时候,必须给定writable参数为True,否则会给予没有权限访问异常。

5、执行位置
 要获取执行位置,除了Application.StartupPath,还可以直接用Assembly.GetEntryAssembly().Location。

6、简单判断内容是否为网页并格式化纯TXT->网页格式
 我的做法是,如果Text中含有任何网页标签对就认为是网页,这有缺陷,但能满足大部分需求。
  private struct HTMLTag
  {
   internal string strPrefix;
   internal string strSuffix;
  }
  private static HTMLTag[] _htmlTags=new HTMLTag[4];
  private static string[] _htmlTagText={"<html", "</html>", "<body", "</body>", "<p", "</p>", "<div", "</div>"};


  public static string ToFormattedHTML(string strHTML)
  {
   for(int i=0; i<_htmlTagText.Length;i+=2)
   {
    _htmlTags[(int)((i + 1) / 2)].strPrefix = _htmlTagText[i];
    _htmlTags[(int)((i + 1) / 2)].strSuffix = _htmlTagText[i + 1];
   }

   string strRet= strHTML;

   if(!IsHTML(strRet))
    strRet = strRet.Replace("\r\n", "<br>\r\n");

   return strRet;
  }

  public static bool IsHTML(string strHTML)
  {
   string strRet = strHTML.ToLower();
   bool blnRet= false;

   for(int i = 0; i<_htmlTags.Length; i++)
   {           
    if(strRet.IndexOf(_htmlTags[i].strPrefix)!=-1 && strRet.IndexOf(_htmlTags[i].strSuffix)!=-1)
    {
     blnRet = true;
     break;
    }
   }
   return blnRet;
  }

7、获取合法目录/文件名
 Windows不允许目录/文件名含有一些非法字符,只需要把这些字符剔除就行了。
  public static string ToNormalFileName(string strFile)
  {
   try
   {
    char[] chrItems=new char[9];
    chrItems[0]='/';
    chrItems[1]='\\';
    chrItems[2]=':';
    chrItems[3]='*';
    chrItems[4]='?';
    chrItems[5]='\"';
    chrItems[6]='<';
    chrItems[7]='>';
    chrItems[8]='|';
    strFile=ReplaceChars(strFile,chrItems);
   }
   catch
   {
   }
   return strFile;
  }

8、发出声音
 这个方法大家都知道了,就是引入Beep WIN32 API
  [DllImport("kernel32")]
  private static extern int Beep(int dwFreq, int dwDuration);

  public static void BeepIt()
  {
   Beep(500,50);
  }