首页 > C#实现一个用于开机启动其他程序的Windows服务

C#实现一个用于开机启动其他程序的Windows服务

今天决定写写博客,不为别的,只当自己的积累,如果与此同时能不误导他人甚至给了朋友们一些启发,那真是更好了!



程序的目的和用途:



很多开机启动程序仅仅加在启动项里面,只有登陆后才真正启动。windows服务在开机未进行用户登录前就启动了。正是利用这一点,解决一些服务器自动重启后特定软件也自动启动的问题。



1.新建一个服务项目 visual C#----windows----windows服务;



2.添加一个dataset(.xsd),用于存储启动目标的路径,日志路径等。



   在dataset可视化编辑中,添加一个datatable,包含两列 StartAppPath 和 LogFilePath。分别用于存储目标的路径、日志路径。



   *我认为利用dataset.xsd存储配置参数的优势在于可以忽略xml解析的具体过程直接使用xml文件。



     在dataset中 提供了ReadXml方法用于读取xml文件并将其转换成内存中的一张datatable表,数据很容易取出来!同样,WriteXml方法用于存储为xml格式的文件,也仅仅需要一句话而已。



3. program.cs文件 作为程序入口,代码如下:



view plaincopy to clipboardprint?

using System.Collections.Generic;  

using System.ServiceProcess;  

using System.Text;  

  

namespace WindowsServices_AutoStart  

{  

    static class Program  

    {  

        ///   

        /// 应用程序的主入口点。  

        ///
  

        static void Main()  

        {  

            ServiceBase[] ServicesToRun;  

  

            // 同一进程中可以运行多个用户服务。若要将  

            // 另一个服务添加到此进程中,请更改下行以  

            // 创建另一个服务对象。例如,  

            //  

            //   ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};  

            //  

            ServicesToRun = new ServiceBase[] { new WindowsServices_AutoStart() };  

  

            ServiceBase.Run(ServicesToRun);  

        }  

    }  

}  

using System.Collections.Generic;

using System.ServiceProcess;

using System.Text;



namespace WindowsServices_AutoStart

{

    static class Program

    {

        ///

        /// 应用程序的主入口点。

        ///


        static void Main()

        {

            ServiceBase[] ServicesToRun;



            // 同一进程中可以运行多个用户服务。若要将

            // 另一个服务添加到此进程中,请更改下行以

            // 创建另一个服务对象。例如,

            //

            //   ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};

            //

            ServicesToRun = new ServiceBase[] { new WindowsServices_AutoStart() };



            ServiceBase.Run(ServicesToRun);

        }

    }

}



4.service.cs主文件,代码如下:



view plaincopy to clipboardprint?

using System;  

using System.Collections.Generic;  

using System.ComponentModel;  

using System.Data;  

using System.IO;  

using System.Diagnostics;  

using System.ServiceProcess;  

using System.Text;  

  

namespace WindowsServices_AutoStart  

{  

    public partial class WindowsServices_AutoStart : ServiceBase  

    {  

        public WindowsServices_AutoStart()  

        {  

            InitializeComponent();  

        }  

        string StartAppPath =""; //@"F:0.exe";  

        string LogFilePath ="";// @"f:WindowsService.txt";  

        protected override void OnStart(string[] args)  

        {  

            string exePath = System.Threading.Thread.GetDomain().BaseDirectory;  

            //  

            if (!File.Exists(exePath + @"ServiceAppPath.xml"))  

            {  

                dsAppPath ds = new dsAppPath();  

                object[] obj=new object[2];  

                obj[0]="0";  

                obj[1]="0";  

                ds.Tables["dtAppPath"].Rows.Add(obj);  

                ds.Tables["dtAppPath"].WriteXml(exePath + @"ServiceAppPath.xml");  

                return;  

            }  

            try  

            {  

                dsAppPath ds = new dsAppPath();  

                ds.Tables["dtAppPath"].ReadXml(exePath + @"ServiceAppPath.xml");  

                DataTable dt = ds.Tables["dtAppPath"];  

                StartAppPath = dt.Rows[0]["StartAppPath"].ToString();  

                LogFilePath = dt.Rows[0]["LogFilePath"].ToString();  

            }  

            catch { return; }  

              

            if (File.Exists(StartAppPath))  

            {  

                try  

                {  

                    Process proc = new Process();  

                    proc.StartInfo.FileName = StartAppPath; //注意路径  

                    //proc.StartInfo.Arguments = "";  

                    proc.Start();  

                }  

                catch (System.Exception ex)  

                {  

                    //MessageBox.Show(this, "找不到帮助文件路径。文件是否被改动或删除? " + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);  

                }  

                FileStream fs = new FileStream(LogFilePath, FileMode.OpenOrCreate, FileAccess.Write);  

                StreamWriter m_streamWriter = new StreamWriter(fs);  

                m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);  

                m_streamWriter.WriteLine("WindowsService: Service Started" + DateTime.Now.ToString() + " ");  

                m_streamWriter.Flush();  

                m_streamWriter.Close();  

                fs.Close();  

            }  

        }  

  

        protected override void OnStop()  

        {  

            try  

            {  

                // TODO: 在此处添加代码以执行停止服务所需的关闭操作。  

                FileStream fs = new FileStream(LogFilePath, FileMode.OpenOrCreate, FileAccess.Write);  

                StreamWriter m_streamWriter = new StreamWriter(fs);  

                m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);  

                m_streamWriter.WriteLine("WindowsService: Service Stopped " + DateTime.Now.ToString() + " ");  

                m_streamWriter.Flush();  

                m_streamWriter.Close();  

                fs.Close();  

            }  

            catch  

            {  

  

            }  

        }  

    }  

}  

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.IO;

using System.Diagnostics;

using System.ServiceProcess;

using System.Text;



namespace WindowsServices_AutoStart

{

    public partial class WindowsServices_AutoStart : ServiceBase

    {

        public WindowsServices_AutoStart()

        {

            InitializeComponent();

        }

        string StartAppPath =""; //@"F:0.exe";

        string LogFilePath ="";// @"f:WindowsService.txt";

        protected override void OnStart(string[] args)

        {

            string exePath = System.Threading.Thread.GetDomain().BaseDirectory;

            //

            if (!File.Exists(exePath + @"ServiceAppPath.xml"))

            {

                dsAppPath ds = new dsAppPath();

                object[] obj=new object[2];

                obj[0]="0";

                obj[1]="0";

                ds.Tables["dtAppPath"].Rows.Add(obj);

                ds.Tables["dtAppPath"].WriteXml(exePath + @"ServiceAppPath.xml");

                return;

            }

            try

            {

                dsAppPath ds = new dsAppPath();

                ds.Tables["dtAppPath"].ReadXml(exePath + @"ServiceAppPath.xml");

                DataTable dt = ds.Tables["dtAppPath"];

                StartAppPath = dt.Rows[0]["StartAppPath"].ToString();

                LogFilePath = dt.Rows[0]["LogFilePath"].ToString();

            }

            catch { return; }

            

            if (File.Exists(StartAppPath))

            {

                try

                {

                    Process proc = new Process();

                    proc.StartInfo.FileName = StartAppPath; //注意路径

                    //proc.StartInfo.Arguments = "";

                    proc.Start();

                }

                catch (System.Exception ex)

                {

                    //MessageBox.Show(this, "找不到帮助文件路径。文件是否被改动或删除? " + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                }

                FileStream fs = new FileStream(LogFilePath, FileMode.OpenOrCreate, FileAccess.Write);

                StreamWriter m_streamWriter = new StreamWriter(fs);

                m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);

                m_streamWriter.WriteLine("WindowsService: Service Started" + DateTime.Now.ToString() + " ");

                m_streamWriter.Flush();

                m_streamWriter.Close();

                fs.Close();

            }

        }



        protected override void OnStop()

        {

            try

            {

                // TODO: 在此处添加代码以执行停止服务所需的关闭操作。

                FileStream fs = new FileStream(LogFilePath, FileMode.OpenOrCreate, FileAccess.Write);

                StreamWriter m_streamWriter = new StreamWriter(fs);

                m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);

                m_streamWriter.WriteLine("WindowsService: Service Stopped " + DateTime.Now.ToString() + " ");

                m_streamWriter.Flush();

                m_streamWriter.Close();

                fs.Close();

            }

            catch

            {



            }

        }

    }

}





5.启动调试,成功时也会弹出一个对话框大致意思是提示服务需要安装。



6.把Debug文件夹下面的.exe执行程序,安装为windows系统服务,安装方法网上很多介绍。我说一种常用的:



安装服务

访问项目中的已编译可执行文件所在的目录。  

用项目的输出作为参数,从命令行运行 InstallUtil.exe。在命令行中输入下列代码:  

installutil yourproject.exe

卸载服务  

用项目的输出作为参数,从命令行运行 InstallUtil.exe。  

installutil /u yourproject.exe



至此,整个服务已经编写,编译,安装完成,你可以在控制面板的管理工具的服务中,看到你编写的服务。



7.安装好了之后在系统服务列表中可以管理服务,这时要注意将服务的属性窗口----登陆----“允许于桌面交互”勾选!这样才能在启动了你要的目标程序后不单单存留于进程。在桌面上也看得到。



8.关于卸载服务,目前有两个概念:一是禁用而已;一是完全删除服务。 前者可以通过服务管理窗口直接完成。后者则需要进入注册表“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices”找到服务名称的文件夹,整个删掉,重新启动电脑后,服务消失。



9.扩展思考:经过修改代码,还可以实现:启动目标程序之前,检测进程中是否存在目标程序,存在则不再次启动

转载于:https://www.cnblogs.com/freedom831215/archive/2009/10/03/1577669.html

更多相关:

  • 菜鸟一枚,正在学习C++ Gui Qt4,整理很零碎,欢迎批评指正   1.窗口标题: QWidget *window = new QWidget; window->setWindowTitle("Enter Your Age"); **************************************** 关于标题...

  • 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 总体思路是: 比较两个链表头节点,较小的插入新链表指针之后,同时较小链表指针向后移动一位 实现如下: ListNode* mergeTwo...

  • 1.直接调用微软socket对象处理 static void Main(string[] args){try{IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });//在3721端口新建一个TcpListener对象TcpListener listener = new...

  •   现在很多地方都会用到zookeeper, 用到它的地方就是为了实现分布式。用到的场景就是服务注册,比如一个集群服务器,需要知道哪些服务器在线,哪些服务器不在线。   ZK有一个功能,就是创建临时节点,当机器启动应用的时候就会连接到一个ZK节点,然后创建一个临时节点,那么通过获取监听该路径,并且获取该路径下的节点数量就知道有哪些服务...

  • 前台到后台java时data日期类型的转化 在实体类中用@DataTimeFormat,这样设置即使传过来是空的字符串也是可以转的,要和前面传过来的格式一致,如 @XmlElement(name="BeginDate") @DateTimeFormat(pattern="yyyy-MM-dd") private Date begin...

  • IHostingEnviroment 获取环境相关洗洗 IsDevelopment()、IsStaging()、IsProduction() 分别为:开发、准生产、生产环境 IsEnviroment("Uat") 自定义环境,比如自定义Uat环境 新建: appsettings.Uat.json文件 {"Enviroment":...

  • 七. DockPanel DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中。停靠面板其实就是在WinForm类似于Dock属性的元 素。DockPanel会对每个子元素进行排序,并停靠在面板的一侧,多个停靠在同侧的元素则按顺序排序。     如果将 LastChild...

  • 该链接有导入,导出源码,我的代码有下链接改写,完善而成的, http://www.cnblogs.com/colder/p/3611906.html using System;using System.Collections.Generic;using System.Linq;using System.Web;using System...

  • 转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 对于SharePoint中已经是Record的Item,我们想要修改他的属性,这在UI界面是无法完成的: 这时需要通过Records.BypassLocks API来完成。设计一个tool,利用Records.BypassLocks...

  • C# async await 学习笔记1(http://www.cnblogs.com/siso/p/3691059.html)  提到了ThreadId是一样的,突然想到在WinForm中,非UI线程是无法直接更新UI线程上的控件的问题。 于是做了如下测试: using System; using System.Collectio...

  • 这周本来是要写一篇Dubbo源码分析的,被突发事件耽搁了,下周有时间再补上。这周,笔者经历了一次服务雪崩。服务雪崩,听到这个词就能想到问题的严重性。是的,整个项目,整条业务线都挂了,从该业务线延伸出来的下游业务线也跟着凉了。笔者是连续三天两夜的忙着处理问题,加起来睡眠时间不足5小时,今天才得以睡个好觉。但事故之后还有很多问题等着去...

  •     由于工作中需要直接从MySQL后台读取数据,所以安装了PHPnow,装的过程中提示Apache安装失败,80端口被占用。     在cmd中输入netstat –ano命令,发现80端口被一个PID为4的服务所占用,打开任务管理器,发现PID为4的进程为系统进程,其描述信息为NT Kernel & System,在服务里面又...

  • Dubbo 2.7 版本增加新特性,新系统开始使用 Dubbo 2.7.1 尝鲜新功能。使用过程中不慎踩到这个版本的 Bug。 系统架构 Spring Boot 2.14-Release + Dubbo 2.7.1 现象 Dubbo 服务者启动成功,正常提供服务,消费者调用偶现失败的情况。错误如下图: 可以看出,主要原因为 ca...

  • 越来越多的软件,开始采用云服务。 云服务只是一个统称,可以分成三大类。 IaaS:基础设施服务,Infrastructure-as-a-servicePaaS:平台服务,Platform-as-a-serviceSaaS:软件服务,Software-as-a-service 它们有什么区别呢? IBM 的软件架构师 Albert...

  • Docker最全教程——从理论到实战(六) 原文:Docker最全教程——从理论到实战(六)托管到腾讯云容器服务 托管到腾讯云容器服务,我们的公众号“magiccodes”已经发布了相关的录屏教程,大家可以结合本篇教程一起查阅。 自建还是托管? 在开始之前,我们先来讨论一个问题——是自建容器服务还是托管到云容器服务? 这里...