【问题标题】:How do I get the Service Display name in C++?如何在 C++ 中获取服务显示名称?
【发布时间】:2012-07-11 15:29:00
【问题描述】:

我正在尝试使用 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 块,但从不显示消息框。不知道为什么?

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

【问题讨论】:

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


    【解决方案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);    
    }
    

    【讨论】:

      【解决方案2】:

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

      在 Window XP 和更早版本上,您需要在服务属性对话框中的 Log On 选项卡下勾选 Allow service to interact with desktop 复选框,以便您的服务显示消息框。

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

      【讨论】:

      • 但是当我只是调试代码时它不应该仍然出现吗?我在调试时无法显示它,甚至无法获取 szKeyName 的值,即使我观看它时它说它找不到指定的符号
      • @Bullsfan127,我不熟悉调试器,因此无法对此发表评论。我尝试使用"TermService" 作为服务名称,它正确显示了一个包含"Terminal Services" 的消息框。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-16
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      相关资源
      最近更新 更多