请教:C#windows服务通过CMD启动程序的释放问题

时间:2021-02-23 20:38:38
本人自己通过C#写了windows服务,处理一些小事的,
今日发现:由于系统开机的程序过多,
所以干脆把这写自动启动的程序通过windows服务启动
于是通过Process类,间接通过CMD命令调用目标程序

服务登录的属性已经设置为“本地系统账户”,而且允许服务与桌面交互

由于部分开机程序是界面互交的
问题就在于“只有服务停止下来 [调用this.Stop()],存在界面互交的程序才可以正常使用”

导致开发过程中,要停止服务,
当服务没有停止的时候
任务管理器的进程都发现挺多cmd.exe
于是在服务里面加了强制结束cmd的代码,结果还是要等到停止服务才可以

于是调用Dispose()释放,但是也没有效果,

由于该服务还有其他用途,不想调用this.Stop()],请问大虾有没有其他办法处理呢?

7 个解决方案

#1


根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Service被阻塞在Process Start这一步操作上;
对于windows服务,建议分开处理,更改如下:
1.windows服务不要设置”本地系统账户”,默认System最高权限即可,不需要在服务里做Process服务启动交互界面
2.在开始-启动菜单里添加交互界面启动,用户登陆即可启动程序

#2


引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Service被阻塞在Process Start这一步操作上;
对于windows服务,建议分开处理……


你说的先后问题,我也没有考虑进去,
因为我测试的时候,正常启动系统后,通过net start 和net stop 调用服务的,
这个时候explorer.exe已经存在了。

目前情况是
如果不以System权限运行,无论服务停不停止都不会正常使用。
我觉得关键应该在于释放不释放的问题,怎么解释存在那么多个cmd进程呢。。。

#3


引用 2 楼 djfemg 的回复:
引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Service被阻塞在Process Start这一步……

1.用日志记录Process调用CMD执行次数,看看是否多次调用了
2.这个Process和Disponse没有关系,一旦Process启动CMD后,Process则会自动由GC处理回收,不会长期驻留内存,我觉得这个地方可能是你系统出现多个CMD进程的原因,如果你在P.Start后立刻判断交互界面是否启动,这样就会出现重复操作,CMD是一个进程指令,添加一个等待指令我觉得可以解决
Process p;
                p.Start();
                p.WaitForExit();
WaitForExit将会阻塞服务,直到CMD退出后才会继续执行

#4


引用 3 楼 carpathia 的回复:
引用 2 楼 djfemg 的回复:

引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Servic……


我代码是:

Process p = new Process();
p.StandardInput.WriteLine(“c:\123.exe”);
StreamReader reader = p.StandardOutput;//CMD窗口返回的信息
p.StandardOutput.Close();
p.StandardError.Close();
p.Close();
reader.Close();

应该不存在WaitForExit将会阻塞服务吧?已经直接close掉了

#5


引用 3 楼 carpathia 的回复:
引用 2 楼 djfemg 的回复:

引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Servic……


你提了一下我,我优化了
Process的调用代码
之前担心cmd出问题,所以没有添加以下代码
p.StandardInput.WriteLine("exit");

现在添加了,就顺利结束了cmd进程,问题就顺利解决了 谢谢

#6


引用 4 楼 djfemg 的回复:
引用 3 楼 carpathia 的回复:
引用 2 楼 djfemg 的回复:

引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以P……

晕,难怪会出现多个CMD了
Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();
            p.StandardInput.Write("c:\\aaa.exe\r\n");
            p.StandardInput.Write("exit\r\n");
            p.WaitForExit(1000);//等待1秒,让cmd有时间去执行execute指令

#7


引用 6 楼 carpathia 的回复:
引用 4 楼 djfemg 的回复:

引用 3 楼 carpathia 的回复:
引用 2 楼 djfemg 的回复:

引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后……



因为后台执行CMD,很多情况会出现CMD交互的情况,
例如 copy命令  很多时候要输入 /Y  之类的,
后台又不知道,目前还没有想到好办法处理。。。。
究竟强制退出还是等待CMD结束呢。。。
矛盾。。。。

#1


根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Service被阻塞在Process Start这一步操作上;
对于windows服务,建议分开处理,更改如下:
1.windows服务不要设置”本地系统账户”,默认System最高权限即可,不需要在服务里做Process服务启动交互界面
2.在开始-启动菜单里添加交互界面启动,用户登陆即可启动程序

#2


引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Service被阻塞在Process Start这一步操作上;
对于windows服务,建议分开处理……


你说的先后问题,我也没有考虑进去,
因为我测试的时候,正常启动系统后,通过net start 和net stop 调用服务的,
这个时候explorer.exe已经存在了。

目前情况是
如果不以System权限运行,无论服务停不停止都不会正常使用。
我觉得关键应该在于释放不释放的问题,怎么解释存在那么多个cmd进程呢。。。

#3


引用 2 楼 djfemg 的回复:
引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Service被阻塞在Process Start这一步……

1.用日志记录Process调用CMD执行次数,看看是否多次调用了
2.这个Process和Disponse没有关系,一旦Process启动CMD后,Process则会自动由GC处理回收,不会长期驻留内存,我觉得这个地方可能是你系统出现多个CMD进程的原因,如果你在P.Start后立刻判断交互界面是否启动,这样就会出现重复操作,CMD是一个进程指令,添加一个等待指令我觉得可以解决
Process p;
                p.Start();
                p.WaitForExit();
WaitForExit将会阻塞服务,直到CMD退出后才会继续执行

#4


引用 3 楼 carpathia 的回复:
引用 2 楼 djfemg 的回复:

引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Servic……


我代码是:

Process p = new Process();
p.StandardInput.WriteLine(“c:\123.exe”);
StreamReader reader = p.StandardOutput;//CMD窗口返回的信息
p.StandardOutput.Close();
p.StandardError.Close();
p.Close();
reader.Close();

应该不存在WaitForExit将会阻塞服务吧?已经直接close掉了

#5


引用 3 楼 carpathia 的回复:
引用 2 楼 djfemg 的回复:

引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以Process进程打开的话,那么很可能Servic……


你提了一下我,我优化了
Process的调用代码
之前担心cmd出问题,所以没有添加以下代码
p.StandardInput.WriteLine("exit");

现在添加了,就顺利结束了cmd进程,问题就顺利解决了 谢谢

#6


引用 4 楼 djfemg 的回复:
引用 3 楼 carpathia 的回复:
引用 2 楼 djfemg 的回复:

引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后才会启动,所以如果你的Service是以P……

晕,难怪会出现多个CMD了
Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();
            p.StandardInput.Write("c:\\aaa.exe\r\n");
            p.StandardInput.Write("exit\r\n");
            p.WaitForExit(1000);//等待1秒,让cmd有时间去执行execute指令

#7


引用 6 楼 carpathia 的回复:
引用 4 楼 djfemg 的回复:

引用 3 楼 carpathia 的回复:
引用 2 楼 djfemg 的回复:

引用 1 楼 carpathia 的回复:
根据你的描述,在Service中,默认以System权限运行,如果改成本地系统账户,则默认会启动,但是不会以Process进程显示交互程序界面,因为图形界面需要explorer.exe系统进程,交互界面程序需要用户登陆后……



因为后台执行CMD,很多情况会出现CMD交互的情况,
例如 copy命令  很多时候要输入 /Y  之类的,
后台又不知道,目前还没有想到好办法处理。。。。
究竟强制退出还是等待CMD结束呢。。。
矛盾。。。。