windows服务发布过程中遇到问题的原因分析及解决方式

发布时间:2014-10-25 2:21:45
来源:分享查询网

在最近的一个应用项目中,采用了双Shell的应用模式,即采用一个LirabaryLib,2个Shell,同时打包在一个应用安装包中,部署之后,EAI.WinForm.App这个窗体Shell用来设置若干服务相关的运行参数,EAI.WinService这个服务Shell用来依据包含参数设置内容的配置文件来后台运行这些服务.结构如下图:   由于优先开发的窗体Shell,所以在后来的服务Shell开发过程中,为了充分复用源码,采用了如下构造方式: 1.开放窗体Shell的服务启动和服务停止入口方法为public; 2.在服务Shell的OnStart方法中进行类似下面的编码:   Executor = new EAI.WinForm();   Executor.RunService(); 3.在服务Shell的OnStop方法中进行类似下面的编码:   Executro.StopService(); 4.在Executor.RunService()的实现包含类似下面的编码:      //写启动日志      //读取当前目录中的配置文件      //从配置文件中创建需要加载的服务组件实例      //写进度日志      //为服务实例包装一个多线程运行器(System.Threading.Timer)      //依据配置文件的配置时点设置多线程运行器的激发时点和周期      //写成功日志 最后,在调式的过程中,发现在服务Shell的运行过程中,启动日志和成功日志被成功写入,但是无论怎样配置config.xml中相关的服务激发时点,都没有服务组件运行的迹象发生。 无奈,创建了一个Console(控制台项目)对OnStart中的代码进行移植,单步跟踪,发现了如下问题:   void Worker_OnSyncException(ExecutorExceptionEventArgs e)         {                        BeginInvoke(WriteLogHandler, new object[] { new System.Text.StringBuilder().Append(e.Service.Name).Append("运行错误:/r/n").Append(e.Exception.Message).ToString() });         } 上述代码在调用中报告错误,原因是没有主窗体(上述代码是EAI.WinForm中的实现,由于相应事件中的写日志方法处在一个并行运行的环境中,因此采用BeginInvoke方式进行方法调用),原来在调用代码中确实没有进行Executor.Show()操作,所以导致以上异常,遂进行以下改造: void Worker_OnSyncException(ExecutorExceptionEventArgs e)         {             if (System.Windows.Forms.Application.OpenForms.Count == 0)             {                 WriteLog(new System.Text.StringBuilder().Append(e.Service.Name).Append("运行错误:/r/n").Append(e.Exception.Message).ToString());             }             else             {                 BeginInvoke(WriteLogHandler, new object[] { new System.Text.StringBuilder().Append(e.Service.Name).Append("运行错误:/r/n").Append(e.Exception.Message).ToString() });             }         } 确保在非窗体运行环境中可以正确调用写日志操作.继续调试,在Console(控制台项目)中服务组件能够被正确定时激活.于是继续回到服务Shell环境中进行测试,发现服务Shell环境中服务组件依旧不能被正确定时激活,无奈之下,分析原因,唯一可能出问题的地方就是读取当前目录中的配置文件方法在Windows.Form环境下和Windows.Service环境下可能存在区别,于是将System.Environment.CurrentDirectory方法替换为System.Windows.Forms.Application.StartupPath,再调试,成功,原来System.Environment.CurrentDirectory在Window.Form环境下Windows.Form环境下和Windows.Console环境下能够获取当前运行目录,而在Windows.Service环境下却获取的是Windows/System32目录,难怪服务组件不能被正确定时激活,因为没有读取到相关的配置文件,应用代码没有加载任何的服务组件实现。 Ps:容错性很高,但是可用性不是太好,呵呵。

返回顶部
查看电脑版