工程单元里:
  Application.ShowMainForm := False;

解决方案 »

  1.   

    我也想到这了,试了一下,果然开机就正常启动了,正高兴,又重启了一次,又不行了。。反复的试了几次发现,在工程里加或不加,托盘都有不出现的时候,竟然不是百发百中,这是什么情况呢?服务启外部程序的时候,用的wtsgetactiveconsolesessionid,然后倒换的token,难道有的时候托盘都建到别的桌面去了?现在启一些有界面的程序没啥问题,带托盘的就时灵时不灵的,求解求解啊
      

  2.   

    试了试后又发现,我把外部程序放到程序-启动菜单里,同时有服务会启动再加上程序-启动菜单里也有,开机后程序的用户名是administrator,基本上百发百中都能正常运行,如果不放程序-启动菜单,只用服务启动,不管托盘成功没有,用户名是system,只不过托盘时灵时不灵,有时候能出现,有时候没反应,那就是说程序-启动菜单比服务的start事件要靠前么?因为我写的只有一个进程实例可以运行,否则关掉自己,所以先运行的那个用户名才是administrator,用服务启动外部程序,托盘时灵时不灵这个问题,求助求助啊
      

  3.   

    是自己的一个小程序A,A运行后隐藏了窗口,并产生一个系统托盘。然后单独有个服务程序B,开机的时候会调用一下A,想实现A开机启动。现在的情况是
    1、开机后A的进程在任务管理器里有,但不见托盘,准确的说是有时候有,有时候没有,没有的时候多
    2、如果把A改成运行后不隐藏窗口,那么开机可以见到A的窗口,但托盘也是时有时无
    3、开机启动后,A的用户名是system
    4、win7和xp都试了,一样的效果
    5、B在start调用A,用的
    WTSGetActiveConsoleSessionId
    WTSQueryUserToken
    openprocesstoken
    AdjustTokenPrivileges
    DuplicateTokenEx
    SetTokenInformation
    CreateEnvironmentBlock
    CreateProcessAsUserA如果设置成运行显示窗口,那么A可以开机运行成功,这说明调exe没啥问题吧,可是托盘呢,跑到哪个桌面去了
      

  4.   

    既然B用CreateProcessAsUser启动A,那不应该“开机启动后,A的用户名是system”啊。
      

  5.   

    是这样的
    用openprocesstoken取下B的tokenid
    用WTSGetActiveConsoleSessionId取下当前活动session的id
    用AdjustTokenPrivileges开下权限
    用DuplicateTokenEx复制B为一个新tokenid
    用SetTokenInformation组合下B的新tokenid和活动sessionid
    再用CreateProcessAsUser建立一个新的进程所以建立的新进程是system用户,登进桌面以后,服务B的会话id是0,启动的程序A会话id是1,用户都是system,现在的问题是,A如果写成不隐藏窗体,那么开机启动后可以见到窗体,但托盘时有时无,如果写成隐藏窗体,那么托盘也是时有时无后来我尝试这样用WTSGetActiveConsoleSessionId取下当前活动session的id
    用WTSQueryUserToken取当前活动sessionid对应的tokenid
    用AdjustTokenPrivileges开下权限
    用DuplicateTokenEx复制为一个新tokenid
    再用CreateProcessAsUser建立一个新的进程开机启动后,A的用户是administrator了,会话id为1,但托盘仍是时有时无,有时甚至A也启动不了了,都是一阵一阵的救命啊
      

  6.   

    在A程序中加个Timer,定时让托盘图标显示。
      

  7.   

    那你应该使用CreateProcessWithLogonW,而不是CreateProcessAsUser。
      

  8.   

    嗯,不显示托盘图标的时候,会不会是Shell_NotifyIcon失败了,我要不要加个while(not Shell_NotifyIcon(...)),直到确保成功呢
    我试试
      

  9.   

    我在A的formcreate加了个while not Shell_NotifyIcon(...) do ;
    重启试了3次,晕,竟然都有托盘图标了,ok了难道就是因为这个地方有时候会失败么,还是A正常运行也是偶然现象,很好奇到底是为哈么11楼大哥提醒用CreateProcessWithLogonW,我也试试哈
      

  10.   

    function CreateProcessWithLogonW(lpUserName, lpDomain, lpPassword: LPCWSTR;
      dwLogonFlags: DWORD; lpApplicationName: LPCWSTR; lpCommandLine: LPWSTR;
      dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: LPCWSTR;
      const lpStartupInfo: STARTUPINFOW; var lpProcessInformation: PROCESS_INFORMATION): BOOL; stdcall;CreateProcessWithLogonW调用的时候还需要用户和密码么?
    那如果不知道当前用哪个用户登录怎么办呢,用token那一系列,至少还可以从服务用system用户启动
      

  11.   

    你可以自己创建一个用户,参考emule的代码,它可以以自己的用户权限运行,但是显示在登录的任意用户的托盘区。
      

  12.   

    今天有试了试,都百发百中了!
    用system用户的服务程序B,取得活动session的token,然后settokeninformation,创建一个system用户的A,在A的create里加了个循环判断,保证托盘添加成功,后来再运行,没发现再有问题了!
    为什么开机服务启动的时候,我这里的托盘大多情况都会失败,这个还不太清楚,不过算是解决了,谢谢大家!15楼大哥提到的建一个自己的用户,是说在安装程序的时候吗?
    我现在这个程序只要在管理员用户下双击,就会自动注册个服务,也还算方便,回头再试那种方法吧,谢谢哦!