最近写了两个程序,都可以以服务进程和窗口进程两种方式运行,由于两类程序都需要入口程序,所以很简单,只要在入口方法代码中判断进入相应分支即可,下面总结一下开发心得。
第一个程序,窗口进程和服务进程的功能一样,都查询一些数据并发送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。
2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

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