想在Window Service程序中实现消息循环,
因为在服务程序中打开的窗体(隐藏显示)中,
无法处理跟窗体消息有关的API函数。请大家帮忙提下建议,谢谢

解决方案 »

  1.   

    无法处理跟窗体消息有关的API函数。可以发自定义消息啊
      

  2.   

    之前用到这个API函数:
    AccessibleObjectFromWindow
    ------------------
    碰到一个比较奇怪的问题: 
    普通的MFC对话框程序中可以使用,并且再增加一个窗体,在新的窗体中也可以使用;
    ------------------
    但是在Window Service程序中,这个函数不能使用,
    并且在Window Service中打开一个新窗体,这个函数也无法使用。
      

  3.   

    AccessibleObjectFromWindow
    The AccessibleObjectFromWindow function retrieves the address of the specified interface to the object associated with the given window. For more information about COM parameter attributes, allocating memory, and freeing memory, see Definitions of Parameter Attributes. STDAPI AccessibleObjectFromWindow(
      HWND hwnd,        //IE浏览器主窗体句柄
      DWORD dwObjectID, //OBJID_CLIENT
      REFIID riid,      //IID_IAccessible 
      void** ppvObject //返回的acc接口
    );
    Parameters
    hwnd 
    [in] Specifies the handle of a window for which an object is to be retrieved. To retrieve an interface pointer to the cursor or caret object, specify NULL and use the appropriate object ID in dwObjectID. 
    dwObjectID 
    [in] Specifies the object ID. This value is one of the standard object identifier constants or a custom object ID such as OBJID_NATIVEOM, which is the object ID for the Microsoft Office native object model. For more information about OBJID_NATIVEOM, see the Res section in this topic. 
    riid 
    [in] Specifies the reference identifier of the requested interface. This value is either IID_IAccessible or IID_IDispatch. 
    ppvObject 
    [out] Address of a pointer variable that receives the address of the specified interface. 
    Return Values
    If successful, returns S_OK. If not successful, returns one of the following or another standard COM error code. 
      

  4.   

    发送自定义消息。
    发送自定义消息。
    发送自定义消息。
    发送自定义消息。
    ControlService( hService,SERVICE_MY_CONTROL, &status);
      

  5.   

    服务程序是不能和桌面交互的,所以凡是涉及到窗口操作的API,在服务程序中都不行,连MessageBox都不能用的。
    你在用CreateService创建服务时对dwServiceType参数加上SERVICE_INTERACTIVE_PROCESS,让它成为交互服务就行了。
      

  6.   

    //服务程序主函数代码如下// MCMN_Service.cpp: implementation of the CMCMN_Service class.
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "MCMN_Service.h"
    #include "winserTest.h"
    #include "winserTestDlg.h"//定义可被外部文件使用的全局变量
    extern CwinserTestApp  theApp;
    extern CMCMN_Service   theService;//设置服务名称和版权等参数
    CMCMN_Service::CMCMN_Service()
    {
    //默认不支持调试
    m_bDebug                = FALSE;m_StrServiceDisplayName = _T("winserTest");//显示的服务名称
    m_StrServiceName        = _T("winserTest");//服务进程名称
    m_StrDependOnServiceName= _T("Microsoft Corporation"); //版权信息
    }//安装服务
    void CMCMN_Service::CmdInstallService()
    {
        SC_HANDLE   schService;
        SC_HANDLE   schSCManager;

        //获取模块名称和完整路径
        TCHAR szPath[512];
        if (GetModuleFileName(NULL, szPath, 512 ) == 0)
        {
            return;
        }

        //打开服务管理工具
        schSCManager = OpenSCManager(
    NULL,                   // machine (NULL == local)
    NULL,                   // database (NULL == default)
    SC_MANAGER_ALL_ACCESS   // access required
    );

        if (schSCManager)
        {   //通过服务管理工具,来创建新的服务
            schService = CreateService(
    schSCManager,               // SCManager database
    TEXT(m_StrServiceName),        // name of service
    TEXT(m_StrServiceDisplayName), // name to display
    SERVICE_ALL_ACCESS,         // desired access
    SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,  // service type
    SERVICE_AUTO_START,         // start type
    SERVICE_ERROR_NORMAL,       // error control type
    szPath,                     // service's binary
    NULL,                       // no load ordering group
    NULL,                       // no tag identifier
    TEXT(m_StrDependOnServiceName),// dependencies
    NULL,                       // LocalSystem account
    NULL);                      // no password

            if (schService)
            {   //释放新创建服务占用的资源
                CloseServiceHandle(schService);
            }

    //释放服务管理工具占用的资源
            CloseServiceHandle(schSCManager);
        }

    //配置服务
    ReconfigureService(m_StrServiceName.GetBuffer(m_StrServiceName.GetLength()+1),"服务测试程序");
    m_StrServiceName.ReleaseBuffer(); //释放资源
    }//删除服务
    void CMCMN_Service::CmdRemoveService()
    {
        SC_HANDLE   schService;
        SC_HANDLE   schSCManager;

        //打开服务管理工具
        schSCManager = OpenSCManager(
    NULL,                   // machine (NULL == local)
    NULL,                   // database (NULL == default)
    SC_MANAGER_ALL_ACCESS   // access required
    );

        if (schSCManager)
        {
    //通过管理工具,打开指定的服务
            schService = OpenService(schSCManager, TEXT(m_StrServiceName), SERVICE_ALL_ACCESS);

            if (schService)
            {
                //停止服务
                if (ControlService( schService, SERVICE_CONTROL_STOP, &m_ssStatus))
                {
                    Sleep(1000);

                    while(QueryServiceStatus(schService, &m_ssStatus))
                    {
        //循环检查服务的状态
                        if (m_ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
                        {
                            Sleep(1000);
                        }
                        else
                            break;
                    }
                }

                // 删除服务
                if (DeleteService(schService) == FALSE)
            CloseServiceHandle(schService);
            }

            CloseServiceHandle(schSCManager);
    }
    }//启动服务(*** 在此处打开一个新窗口***)
    void CMCMN_Service::ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
    {
    //向服务管理工具发送状态信息
    ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0);

    //打开一个隐藏的对话框窗体
    CwinserTestDlg dlg;
    theApp.m_pMainWnd = &dlg;
    dlg.DoModal(); //DoModal方式打开。。
    }//启动服务
    void CMCMN_Service::ServiceStart ()
    { ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0);}//停止服务
    void CMCMN_Service::ServiceStop()
    { ((CwinserTestDlg*)theApp.m_pMainWnd)->EndDialog(0L);}//控制服务
    BOOL WINAPI CMCMN_Service::ControlHandler (DWORD dwCtrlType)
    {
        switch(dwCtrlType)
        {
    //调试模式下停止服务的组合键 Ctrl+C or Ctrl+Break
    case CTRL_BREAK_EVENT:  // use Ctrl+C or Ctrl+Break to simulate
    case CTRL_C_EVENT:      // SERVICE_CONTROL_STOP in debug mode
    theService.ServiceStop(); //停止服务
    return TRUE;
    break;
        }
        return FALSE;
    }void CMCMN_Service::CmdDebugService(int argc, char** argv)
    {
        DWORD dwArgc;
        LPTSTR *lpszArgv;

    #ifdef UNICODE
        lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc));
    #else
        dwArgc   = (DWORD)argc;
        lpszArgv = argv;
    #endif

        SetConsoleCtrlHandler(ControlHandler, TRUE);
        ServiceStart(dwArgc, lpszArgv);
    }void CMCMN_Service::CmdDebugService()
    {
        SetConsoleCtrlHandler(ControlHandler, TRUE);
        ServiceStart();
    }BOOL CMCMN_Service::ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
    {
        static DWORD dwCheckPoint = 1;
        BOOL fResult = TRUE;

        if (!m_bDebug) // when debugging we don't report to the SCM
        {
            if (dwCurrentState == SERVICE_START_PENDING)
                m_ssStatus.dwControlsAccepted = 0;
            else
                m_ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;

            m_ssStatus.dwCurrentState = dwCurrentState;
            m_ssStatus.dwWin32ExitCode = dwWin32ExitCode;
            m_ssStatus.dwWaitHint = dwWaitHint;

            if ( (dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED))
                m_ssStatus.dwCheckPoint = 0;
            else
                m_ssStatus.dwCheckPoint = dwCheckPoint++;

            // Report the status of the service to the service control manager.
            fResult = SetServiceStatus( m_sshStatusHandle, &m_ssStatus);
        }
        return fResult;
    }//主函数
    void CMCMN_Service::ServiceMain(int argc, char **argv)
    {
    SERVICE_TABLE_ENTRY dispatchTable[] =
        {
            { TEXT((LPTSTR)(LPCTSTR)m_StrServiceName), (LPSERVICE_MAIN_FUNCTION)Service_Main },
            { NULL, NULL }
        };

        if ((argc > 1) &&((*argv[1] == '-')||(*argv[1] == '/')))
        {
    //收到安装服务的指令
            if (_stricmp( "install", argv[1]+1 ) == 0)
            {   
                CmdInstallService();
    return;
            }

    //收到删除服务的指令
            else if (_stricmp( "remove", argv[1]+1 ) == 0)
            {   
                CmdRemoveService();
    return;
            }
            else if (_stricmp( "debug", argv[1]+1 ) == 0)
            {   
                m_bDebug = TRUE;
                CmdDebugService(argc, argv);
    return;
            }
        }
        
    StartServiceCtrlDispatcher(dispatchTable); 
    }//主函数
    void CMCMN_Service::ServiceMain(CString strcmd)
    {
    SERVICE_TABLE_ENTRY dispatchTable[] =
        {
            { TEXT((LPTSTR)(LPCTSTR)m_StrServiceName), (LPSERVICE_MAIN_FUNCTION)Service_Main },
            { NULL, NULL }
        };
    if (strcmd=="install")
    {   //安装服务
    CmdInstallService();
    return;
    }
    else if (strcmd=="remove")
    {   //卸载服务
    CmdRemoveService();
    return;
    }
    else if (strcmd=="debug")
    {
    m_bDebug = TRUE;
    CmdDebugService();
    return;
    }
    StartServiceCtrlDispatcher(dispatchTable); 
    }//主函数
    void WINAPI CMCMN_Service::Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)
    {  
    theService.m_sshStatusHandle = RegisterServiceCtrlHandler(TEXT(theService.m_StrServiceName), Service_Ctrl);

        if (theService.m_sshStatusHandle == 0)
    {
    return;
    }

        theService.m_ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
        theService.m_ssStatus.dwServiceSpecificExitCode = 0;

        // report the status to the service control manager.
        if (!theService.ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
    {
    DWORD dwErr =  dwErr = GetLastError();
    theService.ReportStatusToSCMgr(SERVICE_STOPPED, dwErr, 0);
    return;
    }

        theService.ServiceStart(dwArgc, lpszArgv);
    }//控制服务
    void WINAPI CMCMN_Service::Service_Ctrl(DWORD dwCtrlCode)
    {
        switch(dwCtrlCode)
        {
    case SERVICE_CONTROL_STOP:
    theService.ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
    theService.ServiceStop();
    return;

            // Update the service status.
    case SERVICE_CONTROL_INTERROGATE:
    break;

            // invalid control code
    default:
    break;

        }
        //SERVICE_STATUS ssStatus = theApp.theService.GetMCMNServiceStatus();//ssStatus
        theService.ReportStatusToSCMgr(theService.m_ssStatus.dwCurrentState, NO_ERROR, 0);
    }//重新配置服务
    void ReconfigureService(LPSTR lpServiceName, LPSTR lpDesc) 

    SC_HANDLE schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (schSCManager != NULL)
    {
    // Need to acquire database lock before reconfiguring.
    SC_LOCK sclLock = LockServiceDatabase(schSCManager);
    if (sclLock != NULL)
    {
    // Open a handle to the service.
    SC_HANDLE schService = OpenService(
    schSCManager, // SCManager database
    lpServiceName, // name of service
    SERVICE_CHANGE_CONFIG); // need CHANGE access

    if (schService != NULL)
    {
    SERVICE_DESCRIPTION sdBuf;
    sdBuf.lpDescription = lpDesc;
    if (ChangeServiceConfig2(
      schService, SERVICE_CONFIG_DESCRIPTION, &sdBuf))
    {
    //MessageBox(NULL,"Change SUCCESS","",MB_SERVICE_NOTIFICATION); 
    }
    CloseServiceHandle(schService);
    }
    UnlockServiceDatabase(sclLock);
    }
    CloseServiceHandle(schSCManager);
    }
    }
      

  7.   

    //启动服务(*** 在此处打开一个新窗口***)
    void CMCMN_Service::ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
    {
        //向服务管理工具发送状态信息
        ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0);
        
        //打开一个隐藏的对话框窗体
        CwinserTestDlg dlg;
        theApp.m_pMainWnd = &dlg;
        dlg.DoModal(); //DoModal方式打开。。
    }
      

  8.   

    ----------------------------
    创建服务的时候,
    已经加了SERVICE_INTERACTIVE_PROCESS这个参数,
    还是不可以//通过服务管理工具,来创建新的服务
            schService = CreateService(
                schSCManager,               // SCManager database
                TEXT(m_StrServiceName),        // name of service
                TEXT(m_StrServiceDisplayName), // name to display
                SERVICE_ALL_ACCESS,         // desired access
                SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,  // service type
                SERVICE_AUTO_START,         // start type
                SERVICE_ERROR_NORMAL,       // error control type
                szPath,                     // service's binary
                NULL,                       // no load ordering group
                NULL,                       // no tag identifier
                TEXT(m_StrDependOnServiceName),// dependencies
                NULL,                       // LocalSystem account
                NULL);                      // no password
      

  9.   

    windows消息机制 
    http://www.cppblog.com/mzty/archive/2006/11/24/15619.html用Windows Api写一个window的消息循环。
    http://zhidao.baidu.com/question/88881603.html『VC++技术内幕』(第四版)读书笔记
    http://www.cnblogs.com/songyujin/archive/2006/03/21/355122.htmlCREATE DIALOG|create window需要注册窗口类,创建窗口,窗口消息过程,以及消息循环
    http://blog.163.com/wangjinrong_easy/blog/static/10162852720091705017981/用VC++6.0写Windows服务
    http://www.99inf.net/SoftwareDev/VC/28762.htmhttp://www.vckbase.com/document/listdoc.asp?mclsid=13&sclsid=1319