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);
}
}
要实现多线程很容易,大家都知道用以下方法实现:
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);
}