软件日志(系统日志)

自己是个C#菜鸟,写了些小东西,但是调试起来总是很麻烦。后来发现大牛们都用什么“日志”来记录软件执行的操作(好像叫软件日志还是系统日志,我就暂取软件日志),这样便于调试,还有就是在软件发生问题的时候方便查阅,感觉这是一个很好的方法,所以就尝试着加这项功能。

我采用的是用记事本来记录。

1.首先完成最简单的一步:把操作写入指定的txt文件

        public void WriteDiary(string step)
        {
            StreamWriter sw = File.AppendText(fname);
            sw.WriteLine(step);
            sw.Close();
        }
 然后我们来试试看这个简单的函数能否正常执行

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string fname = "C:\\Users\\Zhou\\Desktop\\DiaryFile.txt";
        private void Form1_Load(object sender, EventArgs e)
        {
            FileStream fs = new FileStream(fname, FileMode.Create);//我们以create方式覆盖创建。
            fs.Close();
            WriteDiary("打开日志成功");
        }
        public void WriteDiary(string step)
        {
            step = DateTime.Now + " " + step;
            StreamWriter sw = File.AppendText(fname);
            sw.WriteLine(step);
            sw.Close();
        }
    }

运行后会发现桌面多了个DiaryFile.txt文件,点击打开后里面的内容为:xxxxxxxx  打开日志成功

这就记录了程序执行的操作

在界面添加一个按钮,在单击事件中:

        private void button1_Click(object sender, EventArgs e)
        {
            string t = "你点击了" + this.button1.Text;
            WriteDiary(t);
        }
运行程序,点击刚添加的按钮button1.
打开日志,发现操作已经成功写入。


这样你就记录在程序中自己关系的操作,有据可查。

在你打开这个日志的时候你再点击按钮,发现日志并没有更新,难道是写入错误?这时关闭当前日志,再重新打开日志,发现我们的操作是正常记录了的,只是没有实时更新

但有时候我们希望的是这个日志能实时的显示出来,不需要我们去打开这个txt文件来查看。此时我首先想到的是添加一个窗口,然后在窗口里添加一个listbox,用listbox来显示操作,我尝试并且成功了,这样虽能达到实时显示的目的,但是用户有可能一不小心就把这个窗口给关闭了,这样会导致程序出错,或者不能记录程序的操作等错误。

我们知道这个日志是txt文本文件,是可编辑的,我想能不能通过软件直接更改显示内容。于是百度了一下,给了我一个惊喜。

用SendMessage这个API可以实现这个功能。查看了这个API的参数有我们要更改内容的窗口句柄,还有消息类型,以及更改的内容。获取窗口句柄可以用FindWindow和FindWindowEX这两个API来实现

            IntPtr vHandle = FindWindow("Notepad", "DiaryFile.txt - 记事本");//获取记事本窗口的句柄
            IntPtr txtHandle = FindWindowEx(vHandle, IntPtr.Zero, "Edit", null);//获取记事本文本部分句柄
            SendMessage(txtHandle, WM_SETTEXT, (IntPtr)0, mesg);//设置文本不问内容
因为我们记录一次操作就希望显示的日志更新一下,所以上面这部分内容可以加到写日志的函数中去

        public void WriteDiary(string step)
        {
            step = DateTime.Now + " " + step;
            StreamWriter sw = File.AppendText(fname);
            sw.WriteLine(step);
            sw.Close();
            IntPtr vHandle = FindWindow("Notepad", "DiaryFile.txt - 记事本");//获取记事本句柄
            IntPtr txtHandle = FindWindowEx(vHandle, IntPtr.Zero, "Edit", null);//获取记事本文本部分句柄
            SendMessage(txtHandle, WM_SETTEXT, (IntPtr)0, step);//设置记事本文本部分内容
        }

此时运行程序,打开日志,发现“打开日志成功”,现在点击按钮,发现日志内容是变化了,日志被替换为“你点击了button1”,这并不是我们想要的效果。此时我们关闭日志,再重新打开,发现日志仍然记录了两次操作:“打开日志成功” “你点击了button1”。所以sendMessage这个API只是更改了日志显示的内容,并没有改变日志内存储的数据(相当于你改变了文本,但是没有点击“保存”),那这时我们可以读取日志的内容,然后利用SendMessage来显示。
        public void WriteDiary(string step)
        {
            step = DateTime.Now + " " + step;
            StreamWriter sw = File.AppendText(fname);
            sw.WriteLine(step);
            sw.Close();

            //这里为增加部分,SendMessage里的显示内容要相应更改为msg
            StreamReader sr = new StreamReader(fname);
            string msg = sr.ReadToEnd();//读取日志内容
            sr.Close();

            IntPtr vHandle = FindWindow("Notepad", "DiaryFile.txt - 记事本");//获取记事本句柄
            IntPtr txtHandle = FindWindowEx(vHandle, IntPtr.Zero, "Edit", null);//获取记事本文本部分句柄
            SendMessage(txtHandle, WM_SETTEXT, (IntPtr)0, msg);//设置记事本文本部分内容
        }

此时运行程序,打开日志,日志同样显示:“打开日志成功”,此时点击按钮,日志增加了一条操作:“你点击了按钮就button1”,再点击按钮继续增加。。。。。这时我们关闭日志,单击几次按钮,再次打开日志,发现日志仍然记录了我们的操作。如果你想程序运行时就自动显示日志而不需要手动打开,在load里加一句:Process.Start(fname);就行了

如果你想最新执行的操作显示在最前面,只需要在日志写入的时候修改就行了。把最后执行的操作插入第一行就行了。整个程序如下:

   public partial class Form1 : Form
    {
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

        [DllImport("User32.DLL")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(
        string lpClassName,
        string lpWindowName
        );
        int WM_SETTEXT = 0x000C;
        public Form1()
        {
            InitializeComponent();
        }
        string fname = "C:\\Users\\Zhou\\Desktop\\DiaryFile.txt";
        private void Form1_Load(object sender, EventArgs e)
        {
            FileStream fs = new FileStream(fname, FileMode.Create);//我们以create方式覆盖创建。
            fs.Close();
            Process.Start(fname);
            WriteDiary("打开日志成功");
        }
        public void WriteDiary(string step)
        {

            StreamReader sr = new StreamReader(fname);
            string temp = sr.ReadToEnd();
            sr.Close();
            step = DateTime.Now + " " + step;
            temp = step + "\r\n" + temp;
            StreamWriter sw = new StreamWriter(fname);
            sw.Write(temp);
            sw.Close();

            IntPtr vHandle = FindWindow("Notepad", "DiaryFile.txt - 记事本");//获取记事本句柄
            IntPtr txtHandle = FindWindowEx(vHandle, IntPtr.Zero, "Edit", null);//获取记事本文本部分句柄
            SendMessage(txtHandle, WM_SETTEXT, (IntPtr)0, temp);//设置记事本文本部分内容
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string t = "你点击了" + this.button1.Text;
            WriteDiary(t);
        }
    }

有什么不对的,希望大家批评指正,有更简单的方法,求交流。。。。共同学习



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值