window service 中调用外部exe

nonths 2013-04-18 09:07:04
我自己写了一个window service,想在里面调用一个外部的exe程序,但是每次执行以后总是没有任何反应,也没有报错。但是我用C#写了一个可执行程序,然后用同样的代码在可执行程序中调用外部的exe就可以成功。网上说,要勾选服务的"允许与桌面交互",我也勾选了,但还是没有任何反应。为什么啊?
...全文
535 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
nonths 2013-04-22
  • 打赏
  • 举报
回复
谢谢各位,已经搞定了。 对于楼上各位的建议以及自己的想法做以下总结: 1. 有人说为什么自己不重写一个外部的exe,可以避免调用? 这个我也想过,如果重写外部exe那么简单的话,说都不愿意去调用。我这个主要是因为需要调用到一些底层的驱动,外部exe把这些都写好了,所以直接调用很方便。当然可以自己写的,我也试过,需要调用一些dll动态库,但是一些函数的调用却返回错误,查了原因,还是因为session的问题。 2. 关于“勾选允许与桌面互动”选项 最开始大部分时间浪费在这里。关于调用外部exe的方式有很多种,然后很多人建议说要勾选“允许与桌面互动”,我勾选了却和原来一样。然后我就以为是我调用外部exe的方式不对,搜索各种调用外部exe的方法,最后发现,即使可以,也是弹出一个消息框,可以在另外一个桌面上显示外部exe的窗口,不是我所想要的。 网上的很多东西都是比较老了,这些代码以及方法应该都是针对xp以及以前的系统,对于vista和win7就无效了,最开始不知道,浪费了很多时间。 3. 服务隔离 这里要感谢“gomoku”,你的回答让我知道了我错在哪里了,但是你的回答也不完全正确。我仔细阅读了微软的document,发现虽然默认情况下,服务是运行在session 0下的,与普通的应用程序不在一个session,所以不能互动,但是我们可以利用函数“CreateProcessAsUser”来创建应用程序session下的进程,从而调用外部exe。拨开云雾见日出。走到这一步,问题就明朗,方向也明确了。 这里重发一下链接,以后遇到同样问题的可以参考:http://msdn.microsoft.com/zh-cn/library/windows/hardware/gg463353.aspx 4. 如何利用用createProcessAsUser呢? 看了这个函数的介绍,在网上也有很多例子,大部分是说,需要知道当前用户的用户名和密码,但是这对于个人测试用还可以,如果你作为一个软件release给客户显然不行。网上有高人给出一个解决方法,就是得到一些系统进程的进程token,比如winlog.exe,explorer.exe,然后利用这些进程的token来创建自己的进程。有位高人给出了源码,现在找不到那个链接了,于是自己写了篇文章,把那位大哥的源码贴出来了,如果需要可以参考。http://blog.csdn.net/nonths/article/details/8833854 关于session,我觉得作为一个程序员,还是有必要深入了解下的。
  • 打赏
  • 举报
回复
比如说你的那个“外部的exe程序”能不能重构呢? 能够重构的话最起码让他对启动过程写txt日志文件。 如果不能重构,如果他不是什么“价值几万的源代码”,我建议你重写一个。
  • 打赏
  • 举报
回复
引用 4 楼 Ice_flybird 的回复:
一般来说,service中不调用有互动的EXE,你能不能在service只是调一个中间的EXE。在中间的EXE中再调你现在要调用的EXE. 希望能对你有帮助。
实际上lz使用c#已经写了一个程序而且轻松地调用过exe了。
引用 5 楼 nonths 的回复:
那不是一个道理么?我既然可以调用中间的EXE,也就可以调用我现在要调用的exe了。
所以说单凭你给出的信息,无法理解你的问题。最好就是重做那个exe。
Phenis 2013-04-21
  • 打赏
  • 举报
回复
我试过是可以的,不知道你其它的code有没有问题
nonths 2013-04-19
  • 打赏
  • 举报
回复
引用 1 楼 Phenis 的回复:
string command; ProcessStartInfo psi = new ProcessStartInfo("cmd", "/c " + command); psi.RedirectStandardOutput = true; psi.UseShellExecute = false……
这个方法不行,跟以前的一样。有没有其它办法啊?
gomoku 2013-04-19
  • 打赏
  • 举报
回复
从Vista开始,安全改进就包括了服务隔离(见:http://msdn.microsoft.com/zh-cn/library/windows/hardware/gg463353.aspx)。 服务运行在session 0,并且在特殊的桌面下。因此,没有办法跟用户桌面进行直接交户(改注册表也不行)。 服务创建的进程,默认继承了父进程的环境,也就是在session 0的特殊桌面下。进程可以运行,但同样没有办法直接同用户交户。
nonths 2013-04-19
  • 打赏
  • 举报
回复
引用 4 楼 Ice_flybird 的回复:
一般来说,service中不调用有互动的EXE,你能不能在service只是调一个中间的EXE。在中间的EXE中再调你现在要调用的EXE. 希望能对你有帮助。
那不是一个道理么?我既然可以调用中间的EXE,也就可以调用我现在要调用的exe了。
Ice_flybird 2013-04-19
  • 打赏
  • 举报
回复
一般来说,service中不调用有互动的EXE,你能不能在service只是调一个中间的EXE。在中间的EXE中再调你现在要调用的EXE. 希望能对你有帮助。
  • 打赏
  • 举报
回复
谁让你的那个程序不是.net的控制台程序,并且也不真正支持进程间通讯技术呢?!不管这类。我愿意给你的建议,就是扔掉那个程序,用.net来写。
Phenis 2013-04-18
  • 打赏
  • 举报
回复
string command; ProcessStartInfo psi = new ProcessStartInfo("cmd", "/c " + command); psi.RedirectStandardOutput = true; psi.UseShellExecute = false; psi.CreateNoWindow = true; Process proc = new Process(); proc.StartInfo = psi; proc.Start();

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧