我有一个aaa.exe为NT的Service程序,服务名为aaa, 我要实现:1、以Service运行的时候显示“Service” 即:执行net start aaa
2、以Application运行的时候显示“Application”,即执行c:\>aaa.exe目前我有两种方法实现:1、判断aaa.exe的父进程是否为services.exe, 是则为从service启动运行的,否则就是以application方式启动运行的,但感觉比较麻烦。
2、在WinMain函数执行StartServiceCtrlDispatcher,成功则为service方式,失败则为application方式,但此过程要延迟30秒,令人难以忍受。现在请大家讨论一下更简单的实现方法?

解决方案 »

  1.   

    just check the m_bService variable
    ...
    if(_Module.m_bService)
    {
    OutputDebugString("m_bService");
    }
    else
    {
    OutputDebugString("!m_bService");
    }
        _Module.Start();
    ...
      

  2.   

    masterz:我是用sdk编程的,不是mfc,请教怎么获得m_bService这变量的值?谢谢
      

  3.   

    你同时实现两个入口不是就可以了
    main() for application
    ServiceMain for service
    就不用判断了
      

  4.   

    to bugz:本来就是有两个入口的WinMain和ServiceMain,但是若以service方式启动的时候,WinMain必须执行StartServiceCtrlDispatcher,否则服务无法启动成功,但若不判断是以什么方式启动的话,以Application启动的时候必然也会执行StartServiceCtrlDispatcher,则等待30秒后一定失败,然后才能继续执行Application的代码,现在的关键就是在以Application运行的时候想避免这30秒的延迟,即判断系统是以service启动则执行StartServiceCtrlDispatcher,否则就跳过直接执行Applicaltion的代码。就如masterz说的_Module.m_bService变量,现在问题就是如何获得此变量?
      

  5.   

    masterz给的方法是使用ATL写的service。
      

  6.   

    判断ParentPID是否为services.exe的PID很麻烦吗?
      

  7.   

    to GunRoses:要调用PSAPI.DLL的EnumProcessModules和GetModuleBaseName及NTDLL的NtQueryInformationProcess,还要OpenProcess等。。这的确有点麻烦啊,我的意思是能够判断一个参数或调用一两个函数就能搞定的方法。当然,也可以用检查SID的方法,更麻烦了!
      

  8.   

    用ToolHelp函数会麻烦吗?
    CreateToolhelp32Snapshot+Process32First+Process32Next
    一个循环而已呀
      

  9.   

    GetProcessWindowStation和GetUserObjectInformation有用吗?没试验过。
      

  10.   

    To verybigbug:事实上,你说的这情况只在没有用户登录的情况下才行,在此情况下以SYSTEM的service程序可以打开window station ("WinSta0") 和desktop ("Default"). 而Application程序因为没有用户登录则打开失败,此方法仅仅适用于Service程序随系统启动的时候,但若是有admin用户登录进来后,关闭此服务,然后再启动,则必然无法做出正确判断。我试验过的检测代码如下:int IsService(void)
    {
    char str[1024];
    DWORD len;
    HANDLE hsavewinsta = GetProcessWindowStation();
    if(!hsavewinsta || hsavewinsta == INVALID_HANDLE_VALUE) return 0;
    if(!GetUserObjectInformation(hsavewinsta, UOI_NAME, str, sizeof(str), &len)) return 0;
        if (strnicmp(str, "Service-", 8) == 0) return 1;
    return 0;
    }