如何在C ++中获取服务显示名称?

时间:2012-07-11 15:29:01

标签: c++ winapi visual-c++ windows-services

我正在尝试使用c ++获取正在运行的服务的显示名称。我试图使用GetServiceDisplayName函数但它似乎没有工作,不知道为什么。

TTServiceBegin( const char *svcName, PFNSERVICE pfnService, bool *svc, PFNTERMINATE pfnTerm,
int flags, int argc, char *argv[], DWORD dynamiteThreadWaitTime )
{
SC_HANDLE serviceStatusHandle;
DWORD dwSizeNeeded = 0 ;
TCHAR* szKeyName = NULL ;

serviceStatusHandle=OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE ,SC_MANAGER_ALL_ACCESS);

GetServiceDisplayName(serviceStatusHandle,svcName, NULL, &dwSizeNeeded);
if(dwSizeNeeded)
{
    szKeyName = new char[dwSizeNeeded+1];
    ZeroMemory(szKeyName,dwSizeNeeded+1);
    if(GetServiceDisplayName(serviceStatusHandle ,svcName,szKeyName,&dwSizeNeeded)!=0)
    {
        MessageBox(0,szKeyName,"Got the key name",0);
    }


}        

当我运行此代码时,我永远无法在调试器中看到szKeyName的值,它进入消息框的if块但从不显示消息框。不知道为什么?

无论如何要让它工作以获得服务的显示名称或任何其他/更简单的方法来完成该任务?

2 个答案:

答案 0 :(得分:1)

由于在无法访问桌面的单独会话(Session 0 Isolation)中运行服务的更改,Windows Vista及更高版本将无法显示该消息框,因此消息框将不可见对你,登录用户。

在Window XP及更早版本中,您需要勾选服务属性对话框中登录标签下的Allow service to interact with desktop复选框,以显示服务信息框。

相反,您可以将服务名称写入文件或运行接受要查询的服务名称的用户应用程序,并让它查询并显示服务名称(我只是尝试使用已发布的代码,它可以正常工作,显示消息框。)

答案 1 :(得分:1)

您需要使用WTSSendMessage而不是MessageBox与活动会话进行交互。

WTS_SESSION_INFO* pSessionInfo = NULL;          
DWORD dwSessionsCount = 0;
if(WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwSessionsCount))
{   
    for(int i=0; i<(int)dwSessionsCount; i++)
    {
        WTS_SESSION_INFO &si = pSessionInfo[i];
        if(si.State == WTSActive)
        {                                                       
            DWORD dwIdCurrentSession = si.SessionId;

            std::string strTitle = "Hello";
            std::string strMessage = "This is a message from the service";

            DWORD dwMsgBoxRetValue = 0;
            if(WTSSendMessage(
                WTS_CURRENT_SERVER_HANDLE,
                dwIdCurrentSession,
                (char*)strTitle.c_str(),
                strTitle.size(),
                (char*)strMessage.c_str(),
                strMessage.size(),
                MB_RETRYCANCEL | MB_ICONINFORMATION | MB_TOPMOST,
                60000,
                &dwMsgBoxRetValue,
                TRUE))
            {

                switch(dwMsgBoxRetValue)
                {
                    case IDTIMEOUT:
                        // Deal with TimeOut...
                        break;
                    case IDCANCEL:          
                        // Deal With Cancel....
                        break;
                }               
            }
            else
            {
                // Deal With Error
            }

            break;
        }
    }

    WTSFreeMemory(pSessionInfo);    
}