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.
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); }
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;
// 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 } };
// 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; }
---------------------------- 创建服务的时候, 已经加了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
AccessibleObjectFromWindow
------------------
碰到一个比较奇怪的问题:
普通的MFC对话框程序中可以使用,并且再增加一个窗体,在新的窗体中也可以使用;
------------------
但是在Window Service程序中,这个函数不能使用,
并且在Window Service中打开一个新窗体,这个函数也无法使用。
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.
发送自定义消息。
发送自定义消息。
发送自定义消息。
ControlService( hService,SERVICE_MY_CONTROL, &status);
你在用CreateService创建服务时对dwServiceType参数加上SERVICE_INTERACTIVE_PROCESS,让它成为交互服务就行了。
//////////////////////////////////////////////////////////////////////#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);
}
}
void CMCMN_Service::ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
{
//向服务管理工具发送状态信息
ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0);
//打开一个隐藏的对话框窗体
CwinserTestDlg dlg;
theApp.m_pMainWnd = &dlg;
dlg.DoModal(); //DoModal方式打开。。
}
创建服务的时候,
已经加了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
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