C#创建、安装一个Windows服务

关于WIndows服务的介绍,之前写过一篇:http://blog.csdn.net/yysyangyangyangshan/article/details/7295739。可能这里对如何写一个服务不是很详细。现在纯用代码的形式介绍一下windows服务是如何开发和安装的。
开发环境:Win7 32位;工具:visualstudio2010。
因为win7自带的就有.net环境,算是偷一下懒吧。因为无论是手动安装或程序安装都要用到。一个目录(默认C盘为操作系统的情况):C:\Windows\Microsoft.NET\Framework,如果你的代码是.net2.0:C:\Windows\Microsoft.NET\Framework\v2.0.50727;4.0:C:\Windows\Microsoft.NET\Framework\v4.0.30319。
下面看一下代码:
一、创建windows服务
如图新建一个Windows服务

进入程序如图

空白服务如下

[csharp] view plaincopyprint?

  1. public partial class Service1 : ServiceBase 
  2.    { 
  3.        System.Threading.Timer recordTimer; 
  4.  
  5.  
  6.        public Service1() 
  7.        { 
  8.            InitializeComponent(); 
  9.        } 
  10.  
  11.  
  12.        protected override
    void OnStart(string[] args) 
  13.        { 
  14.        } 
  15.  
  16.  
  17.        protected
    override void OnStop() 
  18.        { 
  19.        } 
  20.    } 
 public partial class Service1 : ServiceBase
    {
        System.Threading.Timer recordTimer;

        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
        }

        protected override void OnStop()
        {
        }
    }

只要在OnStart里完成你的功能代码即可。本例中我们做一个定时向本地文件写记录的功能。
如图

创建一个类,用户写文件,

[csharp] view plaincopyprint?

  1. public class FileOpetation 
  2.    { 
  3.        /// <summary> 
  4.        /// 保存至本地文件 
  5.        /// </summary> 
  6.        /// <param name="ETMID"></param> 
  7.        /// <param name="content"></param> 
  8.        public static
    void SaveRecord(string content) 
  9.        { 
  10.            if (string.IsNullOrEmpty(content)) 
  11.            { 
  12.                return; 
  13.            } 
  14.  
  15.  
  16.            FileStream fileStream = null; 
  17.  
  18.  
  19.            StreamWriter streamWriter =
    null; 
  20.  
  21.  
  22.            try 
  23.            { 
  24.                string path = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
    string.Format("{0:yyyyMMdd}", DateTime.Now)); 
  25.  
  26.  
  27.                using (fileStream =
    new FileStream(path, FileMode.Append, FileAccess.Write)) 
  28.                { 
  29.                    using (streamWriter =
    new StreamWriter(fileStream)) 
  30.                    { 
  31.                        streamWriter.Write(content); 
  32.  
  33.  
  34.                        if (streamWriter !=
    null) 
  35.                        { 
  36.                            streamWriter.Close(); 
  37.                        } 
  38.                    } 
  39.  
  40.  
  41.                    if (fileStream !=
    null) 
  42.                    { 
  43.                        fileStream.Close(); 
  44.                    } 
  45.                } 
  46.            } 
  47.            catch { } 
  48.        } 
  49.    } 
 public class FileOpetation
    {
        /// <summary>
        /// 保存至本地文件
        /// </summary>
        /// <param name="ETMID"></param>
        /// <param name="content"></param>
        public static void SaveRecord(string content)
        {
            if (string.IsNullOrEmpty(content))
            {
                return;
            }

            FileStream fileStream = null;

            StreamWriter streamWriter = null;

            try
            {
                string path = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, string.Format("{0:yyyyMMdd}", DateTime.Now));

                using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write))
                {
                    using (streamWriter = new StreamWriter(fileStream))
                    {
                        streamWriter.Write(content);

                        if (streamWriter != null)
                        {
                            streamWriter.Close();
                        }
                    }

                    if (fileStream != null)
                    {
                        fileStream.Close();
                    }
                }
            }
            catch { }
        }
    }

那么在Service1中调用,

[csharp] view plaincopyprint?

  1. public partial class Service1 : ServiceBase 
  2.    { 
  3.        System.Threading.Timer recordTimer; 
  4.  
  5.  
  6.        public Service1() 
  7.        { 
  8.            InitializeComponent(); 
  9.        } 
  10.  
  11.  
  12.        protected override
    void OnStart(string[] args) 
  13.        { 
  14.            IntialSaveRecord(); 
  15.        } 
  16.  
  17.  
  18.        protected override
    void OnStop() 
  19.        { 
  20.            if (recordTimer !=
    null) 
  21.            { 
  22.                recordTimer.Dispose(); 
  23.            } 
  24.        } 
  25.  
  26.  
  27.        private void IntialSaveRecord() 
  28.        { 
  29.            TimerCallback timerCallback =
    new TimerCallback(CallbackTask); 
  30.  
  31.  
  32.            AutoResetEvent autoEvent = new AutoResetEvent(false); 
  33.  
  34.  
  35.            recordTimer = new System.Threading.Timer(timerCallback, autoEvent, 10000, 60000 * 10); 
  36.        } 
  37.  
  38.  
  39.        private void CallbackTask(Object stateInfo) 
  40.        { 
  41.            FileOpetation.SaveRecord(string.Format(@"当前记录时间:{0},状况:程序运行正常!", DateTime.Now)); 
  42.        } 
  43.    } 
 public partial class Service1 : ServiceBase
    {
        System.Threading.Timer recordTimer;

        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            IntialSaveRecord();
        }

        protected override void OnStop()
        {
            if (recordTimer != null)
            {
                recordTimer.Dispose();
            }
        }

        private void IntialSaveRecord()
        {
            TimerCallback timerCallback = new TimerCallback(CallbackTask);

            AutoResetEvent autoEvent = new AutoResetEvent(false);

            recordTimer = new System.Threading.Timer(timerCallback, autoEvent, 10000, 60000 * 10);
        }

        private void CallbackTask(Object stateInfo)
        {
            FileOpetation.SaveRecord(string.Format(@"当前记录时间:{0},状况:程序运行正常!", DateTime.Now));
        }
    }

这样服务算是写的差不多了,下面添加一个安装类,用于安装。
如图,在service1上右键-添加安装程序,

如图,添加一个安装程序,

如图,添加完成后,

设置相应的属性,给serviceInstaller1设置属性,主要是描述信息。如图,

给serviceProcessInstaller1设置,主要是account。一般选localsystem,如图,

这样服务已经写好了。那么如何添加到windows服务里面去呢。除了之前说过的用CMD,InstallUtil.exe和服务的exe文件进行手动添加。这些可以用代码来实现的。当然主要过程都是一样的。代码实现也是使用dos命令来完成的。
二、代码安装Windows服务
上面写好的服务,最终生成的是一个exe文件。如图,

安装程序安装时需要用到这个exe的路径,所以方便起见,将这个生成的exe文件拷贝至安装程序的运行目录下。

安装代码,

[csharp] view plaincopyprint?

  1. class Program 
  2.     { 
  3.         static void Main(string[] args) 
  4.         { 
  5.              Application.EnableVisualStyles(); 
  6.  
  7.  
  8.             Application.SetCompatibleTextRenderingDefault(false); 
  9.  
  10.  
  11.             string sysDisk = System.Environment.SystemDirectory.Substring(0,3); 
  12.  
  13.  
  14.             string dotNetPath = sysDisk + @"WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe";//因为当前用的是4.0的环境 
  15.  
  16.  
  17.             string serviceEXEPath = Application.StartupPath+@"\MyFirstWindowsService.exe";//把服务的exe程序拷贝到了当前运行目录下,所以用此路径 
  18.  
  19.  
  20.             string serviceInstallCommand =
    string.Format(@"{0}  {1}", dotNetPath, serviceEXEPath);//安装服务时使用的dos命令 
  21.  
  22.  
  23.             string serviceUninstallCommand =
    string.Format(@"{0} -U {1}", dotNetPath, serviceEXEPath);//卸载服务时使用的dos命令 
  24.  
  25.  
  26.             try 
  27.             { 
  28.                 if (File.Exists(dotNetPath)) 
  29.                 { 
  30.                     string[] cmd =
    new string[] { serviceUninstallCommand }; 
  31.  
  32.  
  33.                     string ss = Cmd(cmd); 
  34.  
  35.  
  36.                     CloseProcess("cmd.exe"); 
  37.                 } 
  38.  
  39.  
  40.             } 
  41.             catch 
  42.             { 
  43.             } 
  44.  
  45.  
  46.             Thread.Sleep(1000); 
  47.  
  48.  
  49.             try 
  50.             { 
  51.                 if (File.Exists(dotNetPath)) 
  52.                 { 
  53.                     string[] cmd =
    new string[] { serviceInstallCommand }; 
  54.  
  55.  
  56.                     string ss = Cmd(cmd); 
  57.  
  58.  
  59.                     CloseProcess("cmd.exe"); 
  60.                 } 
  61.  
  62.  
  63.             } 
  64.             catch 
  65.             { 
  66.  
  67.  
  68.             } 
  69.  
  70.  
  71.             try 
  72.             { 
  73.                 Thread.Sleep(3000); 
  74.  
  75.  
  76.                 ServiceController sc = new ServiceController("MyFirstWindowsService"); 
  77.  
  78.  
  79.                 if (sc !=
    null && (sc.Status.Equals(ServiceControllerStatus.Stopped)) || 
  80.  
  81.  
  82.                           (sc.Status.Equals(ServiceControllerStatus.StopPending))) 
  83.                 { 
  84.                     sc.Start(); 
  85.                 } 
  86.                 sc.Refresh(); 
  87.             } 
  88.             catch 
  89.             { 
  90.             } 
  91.         } 
  92.  
  93.  
  94.         /// <summary> 
  95.         /// 运行CMD命令 
  96.         /// </summary> 
  97.         /// <param name="cmd">命令</param> 
  98.         /// <returns></returns> 
  99.         public static
    string Cmd(string[] cmd) 
  100.         { 
  101.             Process p = new Process(); 
  102.             p.StartInfo.FileName = "cmd.exe"; 
  103.             p.StartInfo.UseShellExecute =
    false; 
  104.             p.StartInfo.RedirectStandardInput = true; 
  105.             p.StartInfo.RedirectStandardOutput =
    true; 
  106.             p.StartInfo.RedirectStandardError = true; 
  107.             p.StartInfo.CreateNoWindow =
    true; 
  108.             p.Start(); 
  109.             p.StandardInput.AutoFlush =
    true; 
  110.             for (int i = 0; i < cmd.Length; i++) 
  111.             { 
  112.                 p.StandardInput.WriteLine(cmd[i].ToString()); 
  113.             } 
  114.             p.StandardInput.WriteLine("exit"); 
  115.             string strRst = p.StandardOutput.ReadToEnd(); 
  116.             p.WaitForExit(); 
  117.             p.Close(); 
  118.             return strRst; 
  119.         } 
  120.  
  121.  
  122.         /// <summary> 
  123.         /// 关闭进程 
  124.         /// </summary> 
  125.         /// <param name="ProcName">进程名称</param> 
  126.         /// <returns></returns> 
  127.         public static
    bool CloseProcess(string ProcName) 
  128.         { 
  129.             bool result =
    false; 
  130.             System.Collections.ArrayList procList =
    new System.Collections.ArrayList(); 
  131.             string tempName =
    ""; 
  132.             int begpos; 
  133.             int endpos; 
  134.             foreach (System.Diagnostics.Process thisProc
    in System.Diagnostics.Process.GetProcesses()) 
  135.             { 
  136.                 tempName = thisProc.ToString(); 
  137.                 begpos = tempName.IndexOf("(") + 1; 
  138.                 endpos = tempName.IndexOf(")"); 
  139.                 tempName = tempName.Substring(begpos, endpos - begpos); 
  140.                 procList.Add(tempName); 
  141.                 if (tempName == ProcName) 
  142.                 { 
  143.                     if (!thisProc.CloseMainWindow()) 
  144.                         thisProc.Kill(); // 当发送关闭窗口命令无效时强行结束进程 
  145.                     result = true; 
  146.                 } 
  147.             } 
  148.             return result; 
  149.         } 
  150.     } 
class Program
    {
        static void Main(string[] args)
        {
             Application.EnableVisualStyles();

            Application.SetCompatibleTextRenderingDefault(false);

            string sysDisk = System.Environment.SystemDirectory.Substring(0,3);

            string dotNetPath = sysDisk + @"WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe";//因为当前用的是4.0的环境

            string serviceEXEPath = Application.StartupPath+@"\MyFirstWindowsService.exe";//把服务的exe程序拷贝到了当前运行目录下,所以用此路径

            string serviceInstallCommand = string.Format(@"{0}  {1}", dotNetPath, serviceEXEPath);//安装服务时使用的dos命令

            string serviceUninstallCommand = string.Format(@"{0} -U {1}", dotNetPath, serviceEXEPath);//卸载服务时使用的dos命令

            try
            {
                if (File.Exists(dotNetPath))
                {
                    string[] cmd = new string[] { serviceUninstallCommand };

                    string ss = Cmd(cmd);

                    CloseProcess("cmd.exe");
                }

            }
            catch
            {
            }

            Thread.Sleep(1000);

            try
            {
                if (File.Exists(dotNetPath))
                {
                    string[] cmd = new string[] { serviceInstallCommand };

                    string ss = Cmd(cmd);

                    CloseProcess("cmd.exe");
                }

            }
            catch
            {

            }

            try
            {
                Thread.Sleep(3000);

                ServiceController sc = new ServiceController("MyFirstWindowsService");

                if (sc != null && (sc.Status.Equals(ServiceControllerStatus.Stopped)) ||

                          (sc.Status.Equals(ServiceControllerStatus.StopPending)))
                {
                    sc.Start();
                }
                sc.Refresh();
            }
            catch
            {
            }
        }

        /// <summary>
        /// 运行CMD命令
        /// </summary>
        /// <param name="cmd">命令</param>
        /// <returns></returns>
        public static string Cmd(string[] cmd)
        {
            Process p = new Process();
            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.AutoFlush = true;
            for (int i = 0; i < cmd.Length; i++)
            {
                p.StandardInput.WriteLine(cmd[i].ToString());
            }
            p.StandardInput.WriteLine("exit");
            string strRst = p.StandardOutput.ReadToEnd();
            p.WaitForExit();
            p.Close();
            return strRst;
        }

        /// <summary>
        /// 关闭进程
        /// </summary>
        /// <param name="ProcName">进程名称</param>
        /// <returns></returns>
        public static bool CloseProcess(string ProcName)
        {
            bool result = false;
            System.Collections.ArrayList procList = new System.Collections.ArrayList();
            string tempName = "";
            int begpos;
            int endpos;
            foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
            {
                tempName = thisProc.ToString();
                begpos = tempName.IndexOf("(") + 1;
                endpos = tempName.IndexOf(")");
                tempName = tempName.Substring(begpos, endpos - begpos);
                procList.Add(tempName);
                if (tempName == ProcName)
                {
                    if (!thisProc.CloseMainWindow())
                        thisProc.Kill(); // 当发送关闭窗口命令无效时强行结束进程
                    result = true;
                }
            }
            return result;
        }
    }

这段代码其实可以放在项目中的某个地方,或单独执行程序中,只好设置好dotNetPath和serviceEXEPath路径就可以了。

运行完后,如图,

再在安装目录下看记录的文件,

这样,一个windows服务安装成功了。

代码下载:http://download.csdn.net/detail/yysyangyangyangshan/6032671

时间: 2024-09-12 04:03:19

C#创建、安装一个Windows服务的相关文章

新建了一个windows服务,关机再开机能够自启动,但是用cmd命令行创建此服务需要手动启动

问题描述 有没有什么方法,创建此windows服务之后,不用手动启动,一运行此windows服务,它就自启动了?现在这个windows方法,运行完毕之后,需要手动去启动,但是关机开机之后他能自启动,我想要的是,运行完毕之后能达到像开机关机之后自启动这个情况,希望各位大神指点 解决方案 本帖最后由 a981583536 于 2016-07-11 13:05:10 编辑解决方案二:自己去看下Program.cs的Main函数吧默认如果是服务的话通过ServiceBase.Run来运行你可以自己加个参

任务:消息-使用一个Windows服务来启动WebSphere MQ File Transfer Edition客

任务:消息-使用一个Windows服务来启动WebSphere MQ File Transfer Edition客户端代理 在用户的桌面上用 IBM WebSphere MQ File Transfer Edition 客 户端代理替代 FTP 客户端是向这些文件传输提供企业可见性和可管理性的一个好 方法.用户可以启动 WebSphere MQ File Transfer Edition 代理,或将其放置 到启动文件夹中让 Windows 自动启动它.但如果这个客户端代理需要在 Windows

c++-自己编写的一个windows服务不能启动

问题描述 自己编写的一个windows服务不能启动 我用C++编写了一个简单的windows服务,服务的任务是服务启动后向文件中循环写入文字,我的服务可以安装,但是启动时会显示本地计算机上的 xx服务启动后停止,我的电脑加入了公司的域,请问跟加域有关系吗? 解决方案 你是不是把代码逻辑写在OnStart里面了?你需要在OnStart中启动一个线程,并且用死循环保持住线程,将真正的逻辑写在里面. 解决方案二: 当然,否则OnStart执行完,没有保持住的线程,程序就停了.你可以google一些别人

使用srvany.exe将程序安装成windows服务的详细教程

srvany.exe介绍 srvany.exe是Microsoft Windows Resource Kits工具集的一个实用的小工具,用于将任何EXE程序作为Windows服务运行.也就是说srvany只是其注册程序的服务外壳,这个特性对于我们 来说非常实用,我们可以通过它让我们的程序以SYSTEM账户启动,或者实现随机器启动而自启动,也可以隐藏不必要的窗口,比如说控制台窗口等等. 资源下载 你可以通过下载并安装Microsoft Windows Resource Kits 获得或者直接在本文

怎么解决Win7出现未能连接一个Windows服务?

  近日有网友"所爱隔山海"Win7电脑在开机的时候遇到了开机很慢,开机后提示:未能连接一个Windows服务.如果遇到电脑出现未能连接一个Windows服务该如何解决呢?这就是小编今天要分享的一个电脑小技巧. Win7出现"未能连接一个Windows服务"错误提示,主要是由于电脑系统中的"System Event Notification"服务没有正常开启导致的,可能是用户在使用一些第三方安全软件优化开机启动项的时候,不小心禁用了此服务,只需重

Win7出现未能连接一个Windows服务的解决办法

  近日有网友"所爱隔山海"Win7电脑在开机的时候遇到了开机很慢,开机后提示:未能连接一个Windows服务.如果遇到电脑出现未能连接一个Windows服务该如何解决呢?这就是小编今天要分享的一个电脑小技巧. Win7出现"未能连接一个Windows服务"错误提示,主要是由于电脑系统中的"System Event Notification"服务没有正常开启导致的,可能是用户在使用一些第三方安全软件优化开机启动项的时候,不小心禁用了此服务,只需重

【分享】中文分词服务器源代码&amp;amp;amp;词库,一个简单的webserver,同时又还是一个Scoket server,又是一个windows服务

问题描述 [分享]中文分词服务器源代码&词库,一个简单的webserver,同时又还是一个Scoketserver,又是一个windows服务软件名称:藏拙简易中文分词服务器作者:藏拙具体使用时可将cangzhuo.dat放在分词服务器相同的目录即可使用前请先启动分词服务器藏拙简易中文分词服务器(C语言开发+词库+源代码),最大特色可以让javascript来调用!高速下载地址1:分词服务器程序既是一个windows服务程序,服务名称是:cangzhuofenciserviceandserve0

将 tomcat 安装成 windows 服务

1.下载 tomcat 的windows 压缩包,一般以 .zip ,而且文件名中有 bin 的文件就是 2.解压下载的文件到某一个目录下,eg: TOMCAT_HOME 3.打开 cmd ,运行 %TOMCAT_HOME%/bin/service.bat install 即可将 tomcat 安装成为 windows 服务 4.服务管理窗口(开始 -> 运行 -> cmd ->  services.msc ),找到 apache tomcat 服务(可以在 service.bat 中重

手工把tomcat5安装成windows服务

window 由于习惯直接解压缩,然后拷贝整个tomcat到服务器上,因此需要手工把tomcat安装成windows服务: 利用以下脚本即可实现:remrem NT Service Install/Uninstall scriptremrem Optionsrem install Install the service using Tomcat5 as service name.rem Service is installed using default settings.rem remove