.NET平台应用框架设计与实现

本章的目的是实现一个 Windows服务 的通用框架程序,使用该框架,windows服务开发者不需了解开发 windows服务的细节,
只需实现IService接口,将编译生成的dll文件名、服务类全路径名写在配置文件内,就可以实现windows服务功能的加载和启动。

1.IService

public   interface  IService
{
    
void Start();    // windows 服务启动时会以线程的方式调用这个方法;需要实现什么功能就写这里吧
    void Stop();    // windows 服务关闭时会调用这个方法;有什么需要释放的资源,保存的数据就在这里写吧
    void Initialize(XmlNode configXml);    // 对象初始化的方法,在Start()方法前执行,参数是定义在配置文件中的xml节点
}



2.配置文件

< configuration >
    
< configSections >
        
< section  name ="Framework"  type ="SAF.Configuration.ConfigurationHandler,SAF.Configuration"   />
        
< section  name ="MyApplication"  type ="SAF.Configuration.ConfigurationHandler,SAF.Configuration"   />
    
</ configSections >
    
< Framework  type ="SAF.Configuration.ConfigurationManager,SAF.Configuration" >
        
<!--  windows服务 的配置节点  -->
        
< SAF .WindowsService >
            
<!--  一个 windows服务 的例子  -->
            
< Service  name ="empty"  type ="SAF.WindowsService.EmptyService,SAF.WindowsService" >
                
<!--  用户可自行定义的节点(1个或者多个)  -->
                
< File > C: empEmptyService.txt </ File >
                
<!--  运行用户的配置信息  -->
                
< RunAs  InheritIdentity ="false" >
                    
< Domain > AVANADE-C006T6X </ Domain >
                    
< User > user1 </ User >
                    
< Password > password </ Password >
                
</ RunAs >
            
</ Service >
        
</ SAF.WindowsService >
    
</ Framework >
</ configuration >



3.Windows服务通用框架程序

这一部分主要有3个类:
Service1:windows服务通用框架类;
SecuritySwitchThread:单个服务组建的用户账号切换类;
ProjectInstaller:vs.net生成的,用来安装 windows服务的类。

Service1

//  继承自ServiceBase才能被windows识别为windows服务的实现
public   class  Service1 : System.ServiceProcess.ServiceBase
{
    
/// <summary>
    
/// Required designer variable.
    
/// </summary>

    private ArrayList threadArray = new ArrayList();    // 单个windows服务所在的线程池
    private ArrayList instanceArray = new ArrayList();    // windows服务对象池
    private System.ComponentModel.Container components = null;

    
public Service1()
    
{
        InitializeComponent();
    }


    
// vs.net自动生成的代码
    
// 进程中可以运行的用户服务是Service1,可以添加其它的
    static void Main()
    
{
        System.ServiceProcess.ServiceBase[] ServicesToRun;
        ServicesToRun 
= new System.ServiceProcess.ServiceBase[] new Service1() };
        System.ServiceProcess.ServiceBase.Run(ServicesToRun);
    }


    
/// <summary>
    
/// Required method for Designer support - do not modify
    
/// the contents of this method with the code editor.
    
/// </summary>

    private void InitializeComponent()
    
{
        components 
= new System.ComponentModel.Container();
        
this.ServiceName = "SAF.WindowsService";
    }


    
/// <summary>
    
/// Clean up any resources being used.
    
/// </summary>

    protected override void Dispose( bool disposing )
    
{
        
if( disposing )
        
{
            
if (components != null)
            
{
                components.Dispose();
            }

        }

        
base.Dispose( disposing );
    }


    
/// <summary>
    
/// windows服务启动时要执行的方法
    
/// </summary>

    protected override void OnStart(string[] args)
    
{
        
// 取得配置文件中windows服务节点的信息
        ConfigurationManager cm = (ConfigurationManager)ConfigurationSettings.GetConfig("Framework");
        SAF.Configuration.ServiceConfiguration serviceConfig 
= cm.ServiceConfig;
        XmlNode servicesXml 
= serviceConfig.ServicesXml;

        
// 遍历windows服务节点的子节点
        foreach (XmlNode node in servicesXml.ChildNodes)
        
{   
            
try
            
{
                
string typeInfo;
                
// 建立windows服务对象
                typeInfo =node.Attributes["type"].Value;
                Type type 
= Type.GetType(typeInfo);
                IService instance 
= (IService)Activator.CreateInstance(type);

                
// 初始化windows服务对象
                instance.Initialize(node);
                XmlNode runAs 
= node.SelectSingleNode("RunAs");
                instanceArray.Add(instance);

                
// 使用SecuritySwitchThread 对象处理windows服务对象
                ThreadStart ts = new ThreadStart(instance.Start);
                SecuritySwitchThread sst 
= new SecuritySwitchThread(ts,runAs);
                
// windows服务开始执行
                sst.Start();
                threadArray.Add(sst.BaseThread);
            }

            
catch (Exception ex)
            
{
                
//write to the event log
            }

        }

    }


    
/// <summary>
    
/// delegate used when invoke the OnStop method asynchronous during service shut down.
    
/// </summary>

    public delegate void OnStopDelegate();

    
/// <summary>
    
/// windows服务停止时要执行的方法
    
/// </summary>

    protected override void OnStop()
    
{
        
foreach (object o in instanceArray)
        
{
            
try
            
{
                IService service 
= (IService)o;

                
if (service !=null)
                
{
                    
//invoke the delegate asynchronous to stop each started service.
                    OnStopDelegate osd = new OnStopDelegate(service.Stop);
                    osd.BeginInvoke(
null,null);    // 异步方式通知服务类结束运行
                }

            }

            
catch (Exception ex)
            
{
                
//write to the event log
            }

        }


        
// 给出5秒钟的时间,等待服务完成结束操作
        Thread.Sleep(5000);
        
foreach (object o in threadArray)
        
{
            
try
            
{
                Thread t 
= (Thread)o;

                
if (t !=null)
                
{
                    
// 如果线程还在运行状态,那么强制结束它
                    if (t.IsAlive == true)
                    
{
                        t.Abort();
                    }

                }

            }

            
catch (Exception ex)
            
{
                
//write to the event log
            }

        }

    }

}


SecuritySwitchThread

/// <summary>
/// 用来切换运行用户身份的类
/// </summary>

public   class  SecuritySwitchThread
{
    
private ThreadStart serviceDelegate;
    
private XmlNode runAs;
    
private Thread newT;

    
/// <summary>
    
/// 接受一个委托和一个xml节点作为参数
    
/// </summary>
    
/// <param name="start">the ThreadStart delegate for the target method</param>
    
/// <param name="xml">the configuraiton data contains the user account information</param>

    public SecuritySwitchThread (ThreadStart start, XmlNode xml)
    
{
        serviceDelegate 
= start;
        runAs 
= xml;
        
// create a new thread that calls the WrappingMethod
        newT = new Thread(new ThreadStart(WrappingMethod));
    }


    
public void Start()
    
{
        newT.Start();
    }


    
/// <summary>
    
/// 包装后的方法
    
/// </summary>

    private void WrappingMethod()
    
{
        
// 切换当前使用的用户账号
        bool inheritIdentity = Boolean.Parse(runAs.Attributes["InheritIdentity"].Value);

        
if (inheritIdentity == false)
        
{
            
string userid = runAs.SelectSingleNode("User").InnerText;
            
string password= runAs.SelectSingleNode("Password").InnerText;
            
string domain = runAs.SelectSingleNode("Domain").InnerText;
            
//call the utility class to switch the current thread's security context.
            SecurityUtility su = new SecurityUtility();    // SAF.Utility.SecurityUtility 前面提到过的切换用户的方法
            su.Switch(userid, password,domain);
        }


        
// 实际开始执行线程
        serviceDelegate();
    }


    
/// <summary>
    
/// 实际在运行的线程对象
    
/// </summary>

    public Thread BaseThread
    
{
        
get
        
{
            
return newT;
        }

    }

}

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值