ChinaUnix

各位前辈,小弟拿systray4j.jar及systray4j.dll做了个东东,运行的时候右下角确实出现了托盘图标,而且各个按钮很正常。
但是用wrapper将其做成一个windows下的service后就不行了,图标就是显示不出来,但是服务启动、运行以及LOG中记录的信息一切正常,请问这是怎么回事?帮忙了,谢谢!!!
http://blog.csdn.net/techq/article/details/2905951
http://www.feiesoft.com/windows/cmd/ts_cmd_querysession.htm



 perryhg 回复于:2005-06-18 03:06:22

挺有意思的问题,但是从tomcat的例子来看,做系统service的和tray的似乎是不同的程序,通过tray程序控制service的启动/关闭,但是如果你从系统直接启动service,则绕过了tray程序的控制。

我想到这样解决办法:可以设计一个专用的端口,供tray程序查询service的运行状况,tray程序随着用户登录而启动,没有登录的时候service也能运行,但是登录以后,tray程序开始运行,并获得service的状态,并恢复对service的控制。


 HappyWin 回复于:2005-06-19 19:42:52

版主说得有道理,虽然小弟没有搞很明白。
我的做法是在Application中加了一个Systray的class,然后在Application的main函数中用了new SysTray(),这样在Systray这个类中调用Application的一些static方法来实现控制功能。
奇怪的是有些机器在用wrapper将其做成service后可以显示systray图标并且可以实现一些控制功能,但有些机器就不行,怎么都不显示图标,技术上来讲说不过去啊。但是在机器重启后,即使是service设置成autostart,图标都不会显示。

版主硕的解决办法具体应该怎么搞啊?能否说得更清楚些?小弟用java时间不长,但这个问题迫切需要解决,还麻烦多指点一下,小弟先多谢了。!!


 perryhg 回复于:2005-06-20 06:02:07

我没有做过这个应用,不过我把理解和想法告诉你,希望你等得到一点启示。

首先,systray和service其实是不是一回事情,只是在windows里面,让你看起来好像有关联,其实两者并无实际关联。原因如下:

service是随机器启动而运行的程序,而systray是随用户登录而运行的程序,分清这个区别很重要。

service只要你启动机器,就会运行,但是启动机器不一定意味着登录。如果你做一个服务器应用,你只要打开这个服务器的电源,service 程序就会随着windows的启动而启动。你不一定要登录到服务器的。service可以保证你在没有登录服务器的时候也会运行。如果不是特别的安全要求 的话,service程序通常以local system account这个权限非常高的用户来运行。service只要你不关机,注销登录的时候不会 被强制关闭。

相比之下,systray程序启动windows的时候通常不会运行,而是只有你登录以后才会运行。而且,systray会随着你注销登录 (logoff)而关闭。systray的程序以你登录的用户的身份运行。就是说你以Administrator身份登录,就会以 Administrator权限运行,如果你以一个普通用户登录,则以这个用户的权限运行。如果你程序要求的权限超过你这个用户本身的权限,则会出现拒绝 执行有关操作的错误。

理解了这个特性,你就应该知道,你在service程序里面创建systray的做法是错误的。因为systray程序是随着登录而运行而不是随 系统启动运行的。你的机器启动成功以后,你可以进行多次的登录/注销操作。每次登录以后,创建了一个login的session,也创建了你工作栏(包括 你的systray)的handle,这个handle是随着你登录而创建的。如果你在service程序里面启动systray, service随着 机器启动,但是启动的时候你还没有登录,所以系统里面没有工作栏的handle,程序就不知道把这个systray的图标显示到哪里去。等你登录的时候对 方已经运行过这个创建systray图标的程序了,不会再运行了,那你当然就找不到这个tray图标了。

如果你还不理解,我就举个例子。如果一个法院开庭,被告迟到了,法庭作出了对被告不利的缺席审判,审判完了退庭以后,被告赶到了,这个时候被告找 谁去反驳来为自己辩护呢?你的程序情况就是这样,service在你登录系统之前就已经启动了,等你登录以后,已经错过了执行创建那个tray代码的程 序,所以你当然就看不见那个tray图标了。

正确的做法应该学微软自己的类似的程序,比如sql server.它的服务程序是以sevice启动的,而tray图标是一个独立的exe程 序。service程序不依赖于tray图标就可以启动。这样,只要机器启动,sql server就可以提供服务。同时,当你登录到机器的时候(不管是 本地登录还是远程桌面登录),那个tray程序是随你登录而运行的exe程序,它会根据自己内部的一个协议去查询本机的service程序启动了没有,然 后根据service的运行状态来显示相应的图标在tray里面,启动tray的那个程序可以管理service,但是service却不依赖于 tray。当你logoff以后,tray程序关闭了,但是service仍然继续运行。

总而言之,你应该写独立的service程序和独立的tray程序,两者应该分开运行。service程序通过 java service wrapper来设置为系统service,tray程序应该随系统登录运行。然后tray程序通过某种api和 service程序进行对话。可以参考tomcat在windows下的实现。


 cooljia 回复于:2005-06-20 09:56:50

果然是版主啊, 这个回答实在是很详细!


 HappyWin 回复于:2005-06-21 19:33:54

perryhg版主的分析让小弟真是佩服的五体投地,真的是很透彻。原理我彻底明白了,但实现起来不知道是否超出了我的能力研究的范围,不知道研究这个东西需要多长时间?

tomcat在windows下的实现哪里可以搞到?如果不是很复杂我想看看。如果版主和各位同仁有人研究过,能否在此多加指点一下?多谢了,真的感激版主及各位的热情帮忙!


 perryhg 回复于:2005-06-22 03:42:01

再提点想法吧,

既然你用java service wrapper,里面已经有很多动态管理你的service的方法了,它所提到和service的集成有3种方法,你看看方法2和方法3的例子,我觉得基本已经够你用了。


 HappyWin 回复于:2005-06-23 08:57:03

好的,那我先去研究一下方法2跟方法3,看能不能满足要求。其实我之所以用systray,就是想学习sqlserver的方法来监控Service的运行状态,不知道各位前辈还有什么好的方法没有?

不过我还是有一点不明白,如果说登陆跟服务的启动不是一回事,那我把机器启动然后登陆后,安装Service,这样在我的机器上启动服务显示图标 是没有问题的,而且我换了好几台机器安装服务,然后启动,测试都可以显示图标,但是有的机器就是不显示,操作过程及程序都一样,难道跟登陆的用户名还有关 系?

谢谢了!还请各位前辈帮忙指导


 hoohoo888 回复于:2005-07-12 15:09:22

小弟拙见

[  本帖最后由 hoohoo888 于 2006-10-10 14:48 编辑 ]


 gtohyy 回复于:2005-11-26 15:28:44

版主你好:
         我的系统是ME ,在一次系统启动后出现了SYSTRAY的提示:(本程序不能在DOS下运行,之后本来在的任务栏出现的声音 小图标和其它工具的小图标就不出现在任务栏的右下角了),我去控制面板把声音选项卡中的(在任务栏上显示小图标,打勾了之后按确定便出现SYSTRAY的 提示和开机时的一样,重打开声音选项卡,打起了勾又没有了),现在我在USB插U盘或MP3时就没有那个安全删除硬件的小图标,用起来很不方便,请版主或 其它知道的人帮助我一下,这该如何解决


 perryhg 回复于:2005-11-29 08:31:37

引用: 原帖由 gtohyy 于 2005-11-26 07:28 发表
版主你好:
         我的系统是ME ,在一次系统启动后出现了SYSTRAY的提示:(本程序不能在DOS下运行,之后本来在的任务栏出现的声音小图标和其它工具的小图标就不出现在任务栏的右下角了),我去控制面板把声音 ... 



这个问题好像超出了本版的讨论范围了吧,恕我鄙薄,我也不知道你的问题是什么原因引起的。

你可能感兴趣的:(unix)