首页 > 系统相关 >利用vs.net快速开发windows服务(总结)

利用vs.net快速开发windows服务(总结)

时间:2022-11-27 16:05:47浏览次数:83  
标签:IntPtr 服务 string SERVICE windows int vs sc net


在很多应用中需要做windows服务来操作数据库等操作,比如

(1)一些非常慢的数据库操作,不想一次性去做,想慢慢的通过服务定时去做,比如定时为数据库备份等
(2)在.net Remoting中利用windows服务来做Host

利用vs.net我们可以在几分钟之内建立其windows服务,非常简单

下面说一下步骤1. 新建一个项目
2. 从一个可用的项目模板列表当中选择Windows服务
3. 设计器会以设计模式打开
4. 从工具箱的组件表当中拖动一个Timer对象到这个设计表面上 (注意: 要确保是从组件列表而不是从Windows窗体列表当中使用Timer) 
5. 设置Timer属性,Interval属性200毫秒(1秒进行5次数据库操作)
6. 然后为这个服务填加功能
7.双击这个Timer,然后在里面写一些数据库操作的代码,比如
 SqlConnection conn=new SqlConnection("server=127.0.0.1;database=test;uid=sa;pwd=275280");
   SqlCommand comm=-new SqlCommand("insert into tb1 ('111',11)",conn);
   conn.Open();
   comm.ExecuteNonQuery();
   conn.Close();
8. 将这个服务程序切换到设计视图
9. 右击设计视图选择“添加安装程序”
10. 切换到刚被添加的ProjectInstaller的设计视图
11. 设置serviceInstaller1组件的属性: 
    1) ServiceName = My Sample Service
    2) StartType = Automatic (开机自动运行)
12. 设置serviceProcessInstaller1组件的属性  Account = LocalSystem
13. 改变路径到你项目所在的bin\Debug文件夹位置(如果你以Release模式编译则在bin\Release文件夹)
14. 执行命令“InstallUtil.exe MyWindowsService.exe”注册这个服务,使它建立一个合适的注册项。(InstallUtil这个程序在WINDOWS文件夹\Microsoft.NET\Framework\v1.1.4322下面)
15. 右击桌面上“我的电脑”,选择“管理”就可以打计算机管理控制台
16. 在“服务和应用程序”里面的“服务”部分里,你可以发现你的Windows服务已经包含在服务列表当中了
17. 右击你的服务选择启动就可以启动你的服务了
看看数据库是不是一秒多了5个记录啊

需要注意的是:
如果你修改了这个服务,路径没有变化的话是不需要重新注册服务的,如果路径发生了变化,需要先卸载这个服务InstallUtil.exe /u参数,然后再重新安装这个服务,不能直接安装。还有就是windows服务是没有界面的,不要企图用控制的输出方式来输出一些信息,你只能添加一个EventLog,通过WriteEntry()来写日志。

关于怎么用windows服务来做一个远程服务可以看一下​​​http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT15.asp​​​
问题
用以上说的建立了一个服务,启动后,timer却不起作用,sql不执行,不知道为什么?服务都是顺利启动的,但却不执行任务?

可以在 OnStart() 方法里加上 this.timer1.Enabled = true;
另外看一下this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed); 是否和你的事件关联上

如何实现可插拔的windows服务
如果只是实现普通需求非常容易,可以参考文章里的那几个blog。但是如果要做为一个企业级的应用,往往会有别的场景需求。这里描述了能在不改变系统结构的情况下,可以非常快速的支持新的服务要求,并且以多线程方式支持多种业务逻辑的weindows服务开发方法,最后是一些调试技巧。


这是一个安装和卸载服务的类,有兴趣可以看一下.


using  System;
using  System.Runtime.InteropServices;
namespace  EAE.MyServiceInstaller
{
  class  ServiceInstaller
 {
   #region  Private Variables
   private   string  _servicePath;
   private   string  _serviceName;
   private   string  _serviceDisplayName;
   #endregion  Private Variables
   #region  DLLImport
  [DllImport( " advapi32.dll " )]
   public   static   extern  IntPtr OpenSCManager( string  lpMachineName, string  lpSCDB,  int  scParameter);
  [DllImport( " Advapi32.dll " )]
   public   static   extern  IntPtr CreateService(IntPtr SC_HANDLE, string  lpSvcName, string  lpDisplayName, 
    int  dwDesiredAccess, int  dwServiceType, int  dwStartType, int  dwErrorControl, string  lpPathName, 
    string  lpLoadOrderGroup, int  lpdwTagId, string  lpDependencies, string  lpServiceStartName, string  lpPassword);
  [DllImport( " advapi32.dll " )]
   public   static   extern   void  CloseServiceHandle(IntPtr SCHANDLE);
  [DllImport( " advapi32.dll " )]
   public   static   extern   int  StartService(IntPtr SVHANDLE, int  dwNumServiceArgs, string  lpServiceArgVectors);
  [DllImport( " advapi32.dll " ,SetLastError = true )]
   public   static   extern  IntPtr OpenService(IntPtr SCHANDLE, string  lpSvcName, int  dwNumServiceArgs);
  [DllImport( " advapi32.dll " )]
   public   static   extern   int  DeleteService(IntPtr SVHANDLE);
  [DllImport( " kernel32.dll " )]
   public   static   extern   int  GetLastError();
   #endregion  DLLImport
//    // / 
//    // / 应用程序入口.
//    // / 
//
//   [STAThread]
//   static void Main(string[] args)
//   {
//
//    string svcPath;
//    string svcName;
//    string svcDispName;
//     // 服务程序的路径
//    svcPath = @"d:\service\EAEWS.exe";
//    svcDispName="myEAEWS";
//    svcName= "myEAEWS";
//    ServiceInstaller c = new ServiceInstaller();
//    c.InstallService(svcPath, svcName, svcDispName);
//    Console.Read();
//
//   }

   ///  
   ///  安装和运行
   ///  
   ///  程序路径.
   ///  服务名
   ///  服务显示名称.
   ///  服务安装是否成功.
   public   bool  InstallService( string  svcPath,  string  svcName,  string  svcDispName)
  {
    #region  Constants declaration.
    int  SC_MANAGER_CREATE_SERVICE  =   0x0002 ;
    int  SERVICE_WIN32_OWN_PROCESS  =   0x00000010 ;
    // int SERVICE_DEMAND_START = 0x00000003;
    int  SERVICE_ERROR_NORMAL  =   0x00000001 ;
    int  STANDARD_RIGHTS_REQUIRED  =   0xF0000 ;
    int  SERVICE_QUERY_CONFIG  =   0x0001 ;
    int  SERVICE_CHANGE_CONFIG  =   0x0002 ;
    int  SERVICE_QUERY_STATUS  =   0x0004 ;
    int  SERVICE_ENUMERATE_DEPENDENTS  =   0x0008 ;
    int  SERVICE_START  = 0x0010 ;
    int  SERVICE_STOP  = 0x0020 ;
    int  SERVICE_PAUSE_CONTINUE  = 0x0040 ;
    int  SERVICE_INTERROGATE  = 0x0080 ;
    int  SERVICE_USER_DEFINED_CONTROL  = 0x0100 ;
    int  SERVICE_ALL_ACCESS  =  (STANDARD_RIGHTS_REQUIRED  |  
    SERVICE_QUERY_CONFIG  |
    SERVICE_CHANGE_CONFIG  |
    SERVICE_QUERY_STATUS  |  
    SERVICE_ENUMERATE_DEPENDENTS  |  
    SERVICE_START  |  
    SERVICE_STOP  |  
    SERVICE_PAUSE_CONTINUE  |  
    SERVICE_INTERROGATE  |  
    SERVICE_USER_DEFINED_CONTROL);
    int  SERVICE_AUTO_START  =   0x00000002 ;
    #endregion  Constants declaration.
    try
   {
    IntPtr sc_handle  =  OpenSCManager( null , null ,SC_MANAGER_CREATE_SERVICE);
     if  (sc_handle.ToInt32()  !=   0 )
    {
     IntPtr sv_handle  =  CreateService(sc_handle,svcName,svcDispName,SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,svcPath, null , 0 , null , null , null );
      if (sv_handle.ToInt32()  == 0 )
     {
      CloseServiceHandle(sc_handle);
       return   false ;
     }
      else
     {
       // 试尝启动服务
       int  i  =  StartService(sv_handle, 0 , null );
       if (i == 0 )
      {
        return   false ;
      }
      CloseServiceHandle(sc_handle);
       return   true ;
     }
    }
     else
      return   false ;
   }
    catch (Exception e)
   {
     throw  e;
   }
  }
   ///  
   ///  反安装服务.
   ///  
   ///  服务名.
   public   bool  UnInstallService( string  svcName)
  {
    int  GENERIC_WRITE  =   0x40000000 ;
   IntPtr sc_hndl  =  OpenSCManager( null , null ,GENERIC_WRITE);
    if (sc_hndl.ToInt32()  != 0 )
   {
     int  DELETE  =   0x10000 ;
    IntPtr svc_hndl  =  OpenService(sc_hndl,svcName,DELETE);
     if (svc_hndl.ToInt32()  != 0 )
    { 
      int  i  =  DeleteService(svc_hndl);
      if  (i  !=   0 )
     {
      CloseServiceHandle(sc_hndl);
       return   true ;
     }
      else
     {
      CloseServiceHandle(sc_hndl);
       return   false ;
     }
    }
     else
      return   false ;
   }
    else
     return   false ;
  } 
 }


我用C#写了一个服务,用定时器定时检测,不符合某个条件我就退出服务。
下面的示例使用 ServiceController 类检查 Telnet 服务的当前状态。如果该服务已停止,此示例将启动该服务。如果该服务正在运行,此示例将停止该服务。


//

 Toggle the Telnet service - 

//  If it is started (running, paused, etc), stop the service.

//  If it is stopped, start the service.


ServiceController sc 

=   new  ServiceController( " Telnet " );

Console.WriteLine(

" The Telnet service status is currently set to {0} " , 

sc.Status.ToString());


if  ((sc.Status.Equals(ServiceControllerStatus.Stopped))  ||

    (sc.Status.Equals(ServiceControllerStatus.StopPending)))

{

  

//  Start the service if the current status is stopped.


  Console.WriteLine(

" Starting the Telnet service

利用vs.net快速开发windows服务(总结)_timer

" );

  sc.Start();


else

{

  

//  Stop the service if its status is not set to "Stopped".


  Console.WriteLine(

" Stopping the Telnet service

利用vs.net快速开发windows服务(总结)_timer

" );

  sc.Stop();



//  Refresh and display the current service status.

sc.Refresh();

Console.WriteLine(

" The Telnet service status is now set to {0}. " , sc.Status.ToString());

Windows服务开发相关文章收集



总结

最近公司要我做这个,我看了相关的文章,便整理了一下.


实践的时候也出现了服务不执行操作的现象,希望大家一起共同探讨一下,相互学习.




标签:IntPtr,服务,string,SERVICE,windows,int,vs,sc,net
From: https://blog.51cto.com/u_1236522/5890095

相关文章

  • 调试Windows Service
       通常的处理办法是,在service运行后,在调试器中选择attachtoprocess.   然而这种做法也有一定的局限性,例如在service启动时的OnSta......
  • lvs、haproxy、nginx 负载均衡的比较分析
    对软件实现​​负载均衡​​的几个软件,小D详细看了一下,从性能和稳定上还是LVS最牛,基本达到了F5硬件设备的60%性能,其他几个10%都有点困难。     不过就因为LVS忒牛了,配......
  • Python安装(Windows)
    个人喜欢从官网直接下载具体版本安装,然后通过cmd的pip安装其他包。1、官网下载Python,PythonReleasesforWindows|Python.org2、安装选择允许添加路径到系统环境,选择......
  • 分布式配置统一管理平台-Windows
    这里主要使用到disconf分布式配置管理平台支持window和linux下面是大家window环境步骤和一些操作总结。Git-2.6.4-64-bit.exe 1.下载并解压缩     nginx,解压缩到......
  • 【spark】org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/Strin
    idea中运行spark项目出现:org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z网上的方法很多,最后试成功的只有修改源码的方法1.在源码中找到......
  • 使用 Linux 命令 curl 和 telnet 测试接口连通性
    摘要:接口可用性诊断利器curl和Telnet。综述  Linux中的命令curl是利用URL语法在命令行模式下工作的开源文件传输工具,它可以被用于测试API接口,查看响应头和发出HTT......
  • 死循环--VS开发环境
    首先,C语言分为静区、桟区、静态区,局部变量存放子内存中的桟区的桟区使用:先使用高地址处空间,再使用低地址处空间数组随下标的增长,地址是由低到高变化的分析:i和arr为不同的两......
  • LVS+Keepalived 高可用群集
    LVS+Keepalived高可用群集在这个高度信息化的IT时代,企业的生产系统、业务运营、销售和支持,以及日常管理等环节越来越依赖于计算机信息和服务,对高可用(HA)技术的应用需求......
  • 基于.NetCore开发博客项目 StarBlog - (20) 图片显示优化
    前言我的服务器带宽比较高,博客部署在上面访问的时候几乎没感觉有加载延迟,就没做图片这块的优化,不过最近有小伙伴说博客的图片加载比较慢,那就来把图片优化完善一下吧~目前......
  • VS, VSCode写C/C++代码时, 如何查看二维动态数组的值
    VS(VisualStudio):例:查看第1行的头2列数据,如下图所示 VSCode(VisualStudio):例:查看第1行的头5列数据,第2行的头5列数据,如下图所示......