none
服务进程与一般程序进程通信要注意什么问题 RRS feed

  • 问题

  • 我写了一个服务程序,同时也写了一个与该服务交互的程序,两程序都在同一台机子上运行,我用WM_COPYDATA进行交互, 但用本地账户并打开服务的与桌面交互选项时,用本地localsystem账户登录时,两个进程可以进行通信.但安装到远程服务器上,用系统的administrator账户登录时,都无法通信.后来查询MSDN说用远程账户登录是无法与桌面交互的. 我想问一下各位,大家开发服务程序时(远程机器上运行的)都用什么方式与服务器上的应用程序通信. 很急呀,哪们仁兄做个,帮帮老弟!

    2010年2月1日 3:05

答案

  • 操作系统服务与应用进程通信与一般的两个进程通信是有不同,当用户远程登录或是快速切换用户是原先用本地账户能通信的都不能通信了,我后来是提升了应用进程的令牌:在用户程序的INITINSTANCE里国了如下代码
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken);

    LookupPrivilegeValue(NULL, "SeInteractiveLogonRight", &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
    在服务里程里设置与桌面交互,最后就OK了,
    这是在WINXP WIN2003下,在WIN7 winvista下没测试,
    • 已标记为答案 wang_weid 2010年2月4日 8:08
    2010年2月4日 8:08

全部回复

  • 你不能指望WM_COPYDATA 在两台计算机直线传数据。

    通信的方式主要是几个层面的:

    1) 传输层面的通信,这里主要是指TCP/UDP , 你可以在服务程序上开一个Socket 端口进行侦听,然后客户端程序开Socket端口去连接服务器程序。 这么做的话,你什么数据都可以传,但是不好的地方就是需要自己定义传输控制协议。

    2) 架构在现有应用层协议上的通信。 典型的如在HTTP 协议上做的通信。数据传输协议由HTTP 本身控制,自己只需要关心自己的数据。这里面最最典型的情况就是WebService。服务器端用Java 或者.NET 将服务功能编写为WebService,客户端通过HTTP协议向服务器以POST 方式发送数据,并得到服务器端的计算结果。 使用这种方式都是用标准的通信端口,可以避开网络上的防火墙带来的烦恼。不像直接用Socket 传输需要自定义端口,在网络上开例外,并且还得处理代理的情况。 当然你还可以在HTTP协议上传输其他的协议,比如MSNP。

    3) 基于对象层面的通信。 这里主要是指COM+ .NET Remoting 等等,用户完全不必关心数据的传输和格式。只需关心业务的处理。客户端程序并不直接调用远端服务器程序,而是调用本地的一个服务器程序代理对象,再由代理对象向服务器程序进行数据交互通信。 微软提供的此类通信协议主要是RPC 和WebService。

    一般来说,如果你需要通信的数据种类单一,要求处理速度快,可以考虑直接用Socket。 如果通信协议复杂,就需要使用WebService 或者COM+ 通过RPC 协议进行通信。
    2010年2月1日 3:31
    版主
  • 我是在一台远程机器上,同时运行系统服务和服务监控程序,当我用远程桌面登录上去,发现那个服务器上的服务程序无法和同一个机子上的监控程序通信进行协同工作.

    2010年2月1日 6:58
  • 同一台主机的进程间通信办法多了,共享内存,管道,socket都可以.具体的方法可以很容易在互联网上查到:)


    0xBAADF00D
    2010年2月1日 15:49
    版主
  • 我是在一台远程机器上,同时运行系统服务和服务监控程序,当我用远程桌面登录上去,发现那个服务器上的服务程序无法和同一个机子上的监控程序通信进行协同工作.


    这是因为,你远程登录运行的客户端程序和服务程序根本就不在一个Session 里面。 你用PCAnywhere 登录还差不多。
    2010年2月1日 23:38
    版主
  • 我是在一台远程机器上,同时运行系统服务和服务监控程序,当我用远程桌面登录上去,发现那个服务器上的服务程序无法和同一个机子上的监控程序通信进行协同工作.


    这是因为,你远程登录运行的客户端程序和服务程序根本就不在一个Session 里面。 你用PCAnywhere 登录还差不多。

    的确是你回答的这样,那如何解决这个问题呢,用户不想用PCAnywhere,我也查了一下这是操作系统服务进程与应用进程通信是受安全限制的,现在可以用命名管道加访问控制列表来解决(在创建命名管道时加上安全属性),但比较烦我想用CSocket但SOCKET好象与什么访问控制列表无关在创建时没有什么安全属性类控制.不知行不行.
    2010年2月2日 1:29
  • 同一台主机的进程间通信办法多了,共享内存,管道,socket都可以.具体的方法可以很容易在互联网上查到:)


    0xBAADF00D

    这些我也知道,但关键是操作系统服务进程与应用进程通信与一般的两进程间通信是有区别的,由于涉及到安全问题(用户权限相关)

    2010年2月2日 1:29
  • 同一台主机的进程间通信办法多了,共享内存,管道,socket都可以.具体的方法可以很容易在互联网上查到:)


    0xBAADF00D

    这些我也知道,但关键是操作系统服务进程与应用进程通信与一般的两进程间通信是有区别的,由于涉及到安全问题(用户权限相关)

    你说的不是很正确。 你把你的服务封装成WebService 暴露出来运行在IIS 上,或者做成一个COM 暴露出来运行在COM+ 平台上,都是没有问题的,也没啥安全上的特殊限制。当然你做成Socket 也是可以的。利弊我在前面的帖子已经说过了。
    2010年2月2日 2:27
    版主
  • 同一台主机的进程间通信办法多了,共享内存,管道,socket都可以.具体的方法可以很容易在互联网上查到:)


    0xBAADF00D

    这些我也知道,但关键是操作系统服务进程与应用进程通信与一般的两进程间通信是有区别的,由于涉及到安全问题(用户权限相关)

    你说的不是很正确。 你把你的服务封装成WebService 暴露出来运行在IIS 上,或者做成一个COM 暴露出来运行在COM+ 平台上,都是没有问题的,也没啥安全上的特殊限制。当然你做成Socket 也是可以的。利弊我在前面的帖子已经说过了。
        首先非常感谢你的解答!
        但我目前碰到的是这种情况:只有一个用户经常登录那台服务器,而且那用户对IIS也不熟悉,他要求就是做成一个系统服务,并有一个能与这个服务交互的监控程序.
        开始我认为这本机两个进程通信还不简单吗,也没看MSDN的关于服务的说明,就想当然的用的WM_COPYDATA结果不行,后又用SOCKET进行通信,这两情况下,当用"本地账户"登录并且打开了服务的"本地账户允许与桌面交互"选项时能相互通信外,其它都不行,
    当用远程登录,服务是能是在工作,但服务器上监控程序与服务根本就不能通信.
        后来在网上找到一遍文章:"VS与Win7共舞:系统服务的Session 0隔离",才真正明白了一点点,现在就是想如何最少改动用SOCKET来实现这两个进程通信.socket创建没有什么安全属性呀,不知从哪儿改, 命名管道虽可以但要改好多代码,
     各位仁兄,能指点一下老弟这种情况能SOCKET吗
    2010年2月2日 9:25
  • 操作系统服务与应用进程通信与一般的两个进程通信是有不同,当用户远程登录或是快速切换用户是原先用本地账户能通信的都不能通信了,我后来是提升了应用进程的令牌:在用户程序的INITINSTANCE里国了如下代码
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken);

    LookupPrivilegeValue(NULL, "SeInteractiveLogonRight", &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
    在服务里程里设置与桌面交互,最后就OK了,
    这是在WINXP WIN2003下,在WIN7 winvista下没测试,
    • 已标记为答案 wang_weid 2010年2月4日 8:08
    2010年2月4日 8:08