zoukankan      html  css  js  c++  java
  • C#winform windows服务程序创建与安装

     

    如题,WinForm 和 Windows Service 通信,就是应用程序和系统服务通信,可以看成是进程间的通信。通信的方式有很多,这里只介绍通过消息队列(MessageQueue)方式。理论知识就不介绍了,直接介绍实例吧。

    工程下载 /Files/newspring/WindowsService.rar 

    一、建立工程

    建立3个项目,其中,

    Common 为类库,包含错误日志类(Log.cs)和数据库访问类(MsSql.cs)

    ServiceDemo 为Windows Service服务,包含安装类(Installer1.cs)和服务类(Service1.cs)

    ServiceDesk 为WinForm应用程序,包含一个主窗口类(frmMain.cs)

    这3个项目要实现的功能是,进程间通信,具体怎么通信呢?这里我设计的是用ServiceDesk这个WinForm实时监控ServiceDemo这个系统服务。ServiceDesk和ServiceDemo之间的通信就通过消息队列(MessageQueue)方式。

    对了,补充下理论,消息队列必须安装后才能用,安装步骤如下:

    控制面板->添加或删除程序->添加或删除组件

    选择应用程序服务器详细信息

    勾上消息队列

    安装完就可以通过控制面板->管理工具->计算机管理->服务和应用程序访问了

    二、书写服务

    Service1.cs

    public partial class Service1 : ServiceBase
        {
            Thread m_thread1;

            public Service1()
            {
                InitializeComponent();
            }

            protected override void OnStart(string[] args)
            {
                if (m_thread1 != null && m_thread1.ThreadState != System.Threading.ThreadState.Aborted)
                {
                    m_thread1.Abort();
                }

                m_thread1 = new Thread(new ThreadStart(Work));
                m_thread1.IsBackground = true;
                m_thread1.Start();
            }

            protected override void OnStop()
            {

            }

            private void Work()
            {
                while (true)
                {
                    //try
                    //{
                    //    string sql = "insert into T_Log(DateTime,Description)values('{0}','{1}')";
                    //    sql = String.Format(sql, DateTime.Now.ToString(), "adsf");

                    //    int Result = Common.MsSql.ExecuteNonQuery(sql, this.GetType());
                    //}
                    //catch (Exception e)
                    //{
                    //    Common.Log.Write(e);
                    //}


                    string msg = "消息内容测试";
                    SendMessage(msg);

                    System.Threading.Thread.Sleep(500);
                }
            }

            void SendMessage(string msg)
            {
                try
                {
                    string QueuePath = ".\\private$\\aaaa";
                    MessageQueue MQueue;

                    if (!MessageQueue.Exists(QueuePath))
                    {
                        return;
                    }

                    MQueue = new MessageQueue(QueuePath);

                    System.Messaging.Message Msg = new System.Messaging.Message();
                    Msg.Body = msg;

                    //XML格式化传输量较大
                    //Msg.Formatter = new System.Messaging.XmlMessageFormatter(new Type[] { typeof(string) });
                    Msg.Formatter = new System.Messaging.BinaryMessageFormatter();
                    MQueue.Send(Msg);
                }
                catch (Exception ex)
                {
                    Common.Log.Write(this.GetType(), ex);
                }
            }
        }

    三、书写服务控制(WinForm)

    frmMain.cs

    简单界面

    其中组件引用:

    serviceController1的ServiceName属性设置为 ServiceDemo

    代码:

    public partial class frmMain : Form
        {
            int i = 1;
            Thread t1;
            Thread t2;

            string QueuePath = ".\\private$\\aaaa";

            public frmMain()
            {
                InitializeComponent();
            }

            private void frmMain_Load(object sender, EventArgs e)
            {
                this.notifyIcon1.Icon = new Icon("E:\\WorkSpace\\WindowsService\\ServiceDesk\\Resources\\Icon1.ico");

                frmMain.CheckForIllegalCrossThreadCalls = false;

                t1 = new Thread(new ThreadStart(PrintServiceStatus));
                t1.Start();
            }

            private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
            {
                this.Visible = true;
                this.WindowState = FormWindowState.Normal;
            }
               
            private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
            {
                //取消关闭窗口
                e.Cancel = true;
                //将窗口最小化
                this.WindowState = FormWindowState.Minimized;
                //将窗口隐藏
                this.Visible = false;
            }

            private void toolStripMenuItem1_Click(object sender, EventArgs e)
            {
                this.Visible = true;
                this.WindowState = FormWindowState.Normal;
            }

            private void ToolStripMenuItem2_Click(object sender, EventArgs e)
            {
                notifyIcon1.Visible = false;
               
                Application.Exit();
            }

            /// <summary>
            /// 继续
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void toolStripMenuItem_Continue_Click(object sender, EventArgs e)
            {

            }

            /// <summary>
            /// 执行Cmd命令
            /// </summary>
            public void Cmd(string c)
            {
                System.Diagnostics.Process process = new System.Diagnostics.Process();
                process.StartInfo.FileName = "cmd.exe";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardInput = true;
                process.Start();

                process.StandardInput.WriteLine(c);
                process.StandardInput.AutoFlush = true;
                process.StandardInput.WriteLine("exit");
               
                StreamReader reader = process.StandardOutput;//截取输出流
               
                string output = reader.ReadLine();//每次读取一行
               
                while (!reader.EndOfStream)
                {
                    PrintThrendInfo(output);
                    output = reader.ReadLine();
                }

                process.WaitForExit();
            }

            #region 进度显示
            private void PrintThrendInfo(string Info)
            {
                lock (listView1)
                {
                    try
                    {
                        ListViewItem Item = new ListViewItem(i.ToString());
                        Item.SubItems.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                        Item.SubItems.Add(Info);
                        listView1.Items.Add(Item);
                        //listView1.RedrawItems(i - 1, i - 1, false); //线程中不能用这句
                        i++;
                        if (i >= 1000)
                        {
                            listView1.Items.Clear();
                            i = 1;
                        }
                    }
                    catch (SystemException ex)
                    {
                        Log.Write(this.GetType(),ex);
                    }
                }
            }

            private void PrintThrendInfo(string Info, Color ForeColor)
            {
                //锁定资源
                lock (listView1)
                {
                    try
                    {
                        ListViewItem Item = new ListViewItem(i.ToString());
                        Item.SubItems.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                        Item.SubItems.Add(Info);
                        listView1.Items.Add(Item);
                        Item.ForeColor = ForeColor;
                        if (ForeColor == Color.Red || ForeColor == Color.Fuchsia)
                        {
                            Log.Write(this.GetType(), Info);
                        }
                        //listView1.RedrawItems(i - 1, i - 1, false); //线程中不能用这句
                        i++;
                        if (i >= 10000)
                        {
                            listView1.Items.Clear();
                            i = 1;
                        }
                    }
                    catch (SystemException ex)
                    {
                        Log.Write(this.GetType(),ex);
                    }
                }
            }
            #endregion

            /// <summary>
            /// 安装
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnInstall_Click(object sender, EventArgs e)
            {
                try
                {
                    t2.Abort();
                }
                catch { }

                t2 = new Thread(new ThreadStart(Install));
                t2.Start();
            }

            void Install()
            {
                t1.Suspend();
                string c = @"c:\windows\microsoft.net\framework\v2.0.50727\InstallUtil.exe " + AppDomain.CurrentDomain.BaseDirectory + "ServiceDemo.exe";
                Cmd(c);
                t1.Resume();
            }

            /// <summary>
            /// 卸载
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnUninstall_Click(object sender, EventArgs e)
            {
                try
                {
                    t2.Abort();
                }
                catch { }

                t2 = new Thread(new ThreadStart(Uninstall));
                t2.Start();
            }

            void Uninstall()
            {
                t1.Suspend();
                string c = @"c:\windows\microsoft.net\framework\v2.0.50727\InstallUtil.exe /u " + AppDomain.CurrentDomain.BaseDirectory + "ServiceDemo.exe";
                Cmd(c);
                t1.Resume();
            }

            /// <summary>
            /// 启动
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnStart_Click(object sender, EventArgs e)
            {
                try
                {
                    t2.Abort();
                }
                catch { }

                t2 = new Thread(new ThreadStart(Start));
                t2.Start();
            }

            void Start()
            {
                t1.Suspend();
                string c = @"net start ServiceDemo";
                Cmd(c);
                t1.Resume();
            }

            /// <summary>
            /// 停止
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnStop_Click(object sender, EventArgs e)
            {
                try
                {
                    t2.Abort();
                }
                catch { }

                t2 = new Thread(new ThreadStart(Stop));
                t2.Start();
            }

            void Stop()
            {
                t1.Suspend();
                string c = @"net stop ServiceDemo";
                Cmd(c);
                t1.Resume();
            }

            private void PrintServiceStatus()
            {
                if (MessageQueue.Exists(QueuePath))
                {
                    MessageQueue.Delete(QueuePath);
                }

                while (true)
                {
                    t1.Join(1000);

                    this.serviceController1.Refresh();

                    if (this.serviceController1.Status != ServiceControllerStatus.Running)
                    {
                        PrintThrendInfo("服务运行状态:" + this.serviceController1.Status.ToString());

                        if (MessageQueue.Exists(QueuePath))
                        {
                            MessageQueue.Delete(QueuePath);
                        }

                        continue;
                    }

                    MessageQueue MQueue;

                    if (MessageQueue.Exists(QueuePath))
                    {
                        MQueue = new MessageQueue(QueuePath);
                    }
                    else
                    {
                        MQueue = MessageQueue.Create(QueuePath);
                        MQueue.SetPermissions("Administrators", MessageQueueAccessRights.FullControl);
                        MQueue.Label = QueuePath;
                    }

                    //一次读一条,取一条自动去掉读取的这一条
                    //System.Messaging.Message Msg = MQueue.Receive(new TimeSpan(0, 0, 2));

                    //一次读取全部消息,但是不去除读过的消息
                    System.Messaging.Message[] Msg = MQueue.GetAllMessages();
                    //删除所有消息
                    MQueue.Purge();

                    foreach (System.Messaging.Message m in Msg)
                    {
                        //XML格式化传输量较大
                        //Msg.Formatter = new System.Messaging.XmlMessageFormatter(new Type[] { typeof(string) });

                        m.Formatter = new System.Messaging.BinaryMessageFormatter();
                        PrintThrendInfo(m.Body.ToString());
                    }
                }
            }
        }

    三、制作安装

    Installer1.cs

    [RunInstaller(true)]
        public partial class Installer1 : Installer
        {
            public Installer1()
            {
                InitializeComponent();
            }

            public override void Install(IDictionary stateSaver)
            {
                Microsoft.Win32.RegistryKey system;
                    //HKEY_LOCAL_MACHINE\Services\CurrentControlSet
                Microsoft.Win32.RegistryKey currentControlSet;
                    //...\Services
                Microsoft.Win32.RegistryKey services;
                            //...\<Service Name>
                Microsoft.Win32.RegistryKey service;
                            //...\Parameters - this is where you can put service-specific configuration
                Microsoft.Win32.RegistryKey config;
                try
                {
                    //Let the project installer do its job
                    base.Install(stateSaver);

                    //Open the HKEY_LOCAL_MACHINE\SYSTEM key
                    system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
                    //Open CurrentControlSet
                    currentControlSet = system.OpenSubKey("CurrentControlSet");
                    //Go to the services key
                    services = currentControlSet.OpenSubKey("Services");
                    //Open the key for your service, and allow writing
                    service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);
                    //Add your service's description as a REG_SZ value named "Description"
                    service.SetValue("Description", "计划按时执行,如一分钟一次");
                    //(Optional) Add some custom information your service will use...
                    //允许服务与桌面交互
                    service.SetValue("Type", 0x00000110);
                    config = service.CreateSubKey("Parameters");
                }
                catch (Exception e)
                {
                    Console.WriteLine("An exception was thrown during service installation:\n" + e.ToString());
                }
            }

            public override void Uninstall(IDictionary savedState)
            {
                Microsoft.Win32.RegistryKey system;
                Microsoft.Win32.RegistryKey currentControlSet;
                Microsoft.Win32.RegistryKey services;
                Microsoft.Win32.RegistryKey service;

                try
                {
                    //Drill down to the service key and open it with write permission
                    system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
                    currentControlSet = system.OpenSubKey("CurrentControlSet");
                    services = currentControlSet.OpenSubKey("Services");
                    service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);
                    //Delete any keys you created during installation (or that your service created)
                    service.DeleteSubKeyTree("Parameters");
                    //...
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception encountered while uninstalling service:\n" + e.ToString());
                }
                finally
                {
                    //Let the project installer do its job
                    base.Uninstall(savedState);
                }
            }
        }

    四、运行效果

    1、安装效果

    2、运行

    3、卸载

  • 相关阅读:
    JavaWeb--HttpSession案例
    codeforces B. Balls Game 解题报告
    hdu 1711 Number Sequence 解题报告
    codeforces B. Online Meeting 解题报告
    ZOJ 3706 Break Standard Weight 解题报告
    codeforces C. Magic Formulas 解题报告
    codeforces B. Sereja and Mirroring 解题报告
    zoj 1109 Language of FatMouse 解题报告
    hdu 1361.Parencodings 解题报告
    hdu 1004 Let the Balloon Rise 解题报告
  • 原文地址:https://www.cnblogs.com/xiaofengfeng/p/2193952.html
Copyright © 2011-2022 走看看