将后台服务进程和窗口设置进程集成为一个程序
最近写了两个程序,都可以以服务进程和窗口进程两种方式运行,由于两类程序都需要入口程序,所以很简单,只要在入口方法代码中判断进入相应分支即可,下面总结一下开发心得。
第一个程序,窗口进程和服务进程的功能一样,都查询一些数据并发送Email。窗口程序需要从快捷方式加一个参M来运行(按第二个程序的方式可以不用参数判断)。代码如下:
1
class Program
2
{
3
/// <summary>
4
/// 应用程序的主入口点。
5
/// </summary>
6
[STAThread]
7
static void Main(string[] args)
8
{
9
10
// 同一进程中可以运行多个用户服务。若要将
11
// 另一个服务添加到此进程中,请更改下行以
12
// 创建另一个服务对象。例如,
13
//
14
// ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};
15
//
16
if (args.Length > 0 && (args[0].ToUpper() == "/M" || args[0].ToUpper() == "-M"))
17
{
18
Application.EnableVisualStyles();
19
Application.SetCompatibleTextRenderingDefault(false);
20
Application.Run(new MainForm());
21
}
22
else
23
{
24
ServiceBase[] ServicesToRun;
25
ServicesToRun = new ServiceBase[] { new Service1() };
26
ServiceBase.Run(ServicesToRun);
27
}
28
}
29
30
采用定时器时注意,窗口程序用System.Windows.Forms.Timer,而服务程序要用System.Threading.Timer。
class Program2
{3
/// <summary>4
/// 应用程序的主入口点。5
/// </summary>6
[STAThread]7
static void Main(string[] args)8
{9

10
// 同一进程中可以运行多个用户服务。若要将11
// 另一个服务添加到此进程中,请更改下行以12
// 创建另一个服务对象。例如,13
//14
// ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};15
//16
if (args.Length > 0 && (args[0].ToUpper() == "/M" || args[0].ToUpper() == "-M"))17
{18
Application.EnableVisualStyles();19
Application.SetCompatibleTextRenderingDefault(false);20
Application.Run(new MainForm());21
}22
else23
{24
ServiceBase[] ServicesToRun;25
ServicesToRun = new ServiceBase[] { new Service1() };26
ServiceBase.Run(ServicesToRun);27
}28
}29

30

第二个程序,窗口进程用于设置参数,保存于App.config,服务进程用于定时运行。代码如下:
1
static class Program
2
{
3
/// <summary>
4
/// 应用程序的主入口点。
5
/// </summary>
6
static void Main(string[] args)
7
{
8
bool b = false;
9
System.ServiceProcess.ServiceController[] services;
10
services = System.ServiceProcess.ServiceController.GetServices();
11
for (int i = 0; i < services.Length; i++)
12
{
13
if (services[i].Status == System.ServiceProcess.ServiceControllerStatus.StartPending &&
14
services[i].ServiceName == "Service2")
15
{
16
b = true;
17
break;
18
}
19
}
20
if (b)
21
{
22
ServiceBase[] ServicesToRun;
23
ServicesToRun = new ServiceBase[] { new Service2() };
24
ServiceBase.Run(ServicesToRun);
25
}
26
else
27
{
28
Application.EnableVisualStyles();
29
Application.SetCompatibleTextRenderingDefault(false);
30
Application.Run(new Main());
31
}
32
}
33
}
34
static class Program2
{3
/// <summary>4
/// 应用程序的主入口点。5
/// </summary>6
static void Main(string[] args)7
{8
bool b = false;9
System.ServiceProcess.ServiceController[] services;10
services = System.ServiceProcess.ServiceController.GetServices();11
for (int i = 0; i < services.Length; i++)12
{13
if (services[i].Status == System.ServiceProcess.ServiceControllerStatus.StartPending &&14
services[i].ServiceName == "Service2")15
{16
b = true;17
break;18
}19
}20
if (b)21
{22
ServiceBase[] ServicesToRun;23
ServicesToRun = new ServiceBase[] { new Service2() };24
ServiceBase.Run(ServicesToRun);25
}26
else27
{28
Application.EnableVisualStyles();29
Application.SetCompatibleTextRenderingDefault(false);30
Application.Run(new Main());31
}32
}33
}34

将后台服务进程和窗口设置进程集成为一个程序,这种方案可以在程序中采用同一商业逻辑层代码,可以读取同一App.config设置,还可以在窗口进程中控制服务进程的启动和停止。采用入口方法进行分支,然后运行各自的代码,代码很简单,也很实用。
但还有以下两个问题,待高手指点。
1. App.config设置只在进程启动时读取一遍,更改的设置只有重启进程后才生效。
2. 服务需要用InstallUtil.exe来安装和卸载,如果能在窗口进程中安装和卸载就好了。
专注数据库技术,学以致用。

浙公网安备 33010602011771号