1

我有一个 COM Server ,我想将它用作服务。我的应用程序有一个安装程序组件,它在本地系统中创建一个用户 (CN_Service) 并使用以下命令将此 COM 服务器安装为服务:

Connect.exe /service /noreinstall /user:CN_Service /password:somePassword /depends:lanmanworkstation

我有另一个组件,它负责启动这个已安装的服务。在其 winmain() 中,我使用以下代码注册 COM 服务器类对象(在 SUSPENDED 模式下),它成功注册了对象并将 HRESULT 作为 S_OK 返回,这与预期的一样。

int CAppModule::WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /* lpCmdLine */, int nShowCmd)
{
    ::AfxSetResourceHandle(hInstance);
    _strServiceName.LoadString(IDS_SRVL_SERVICENAME);
    _strDisplayName.LoadString(IDS_SRVL_DISPLAYNAME);

    VERIFY(gNTEventLog.SetSource(_strDisplayName));

    // Copy parameters
    m_hInstance = hInstance;
    m_nCmdShow  = nShowCmd;
    _strCmdLine = ::GetCommandLine();

    _qappmodel->InitCOMSupport();   //::CoInitializeEx(NULL, COINIT_MULTITHREADED);

    // Process command line options
    bool bContinue = true;

    int nExitCode = 0;
    if (ProcessCommandLine(_strCmdLine, &bContinue) && bContinue)
    {
        if (_patlmodule != NULL)
        {
        //_patlmodule is an interface pointer and private member of CAppModule 
            HRESULT hr = _patlmodule->RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
            if (FAILED(hr))
            {
                ASSERT_NOT_REACHED();
                gNTEventLog.LogHR(_T("Failed to register the class objects"), hr);
                return 2;
            }
        }

        nExitCode = InternalWinMain();

        if (_patlmodule != NULL)
        {
            _patlmodule->RevokeClassObjects();
        }
    }

    _qappmodel->UninitCOMSupport();

    // When we get here, the service has been stopped
    return nExitCode;
}

但是当我尝试使用 ::CoResumeClassObjects() 恢复注册的类对象时,它会抛出一个错误“无法恢复类对象”,并带有 HRESULT 值:

800706c6(数组边界无效)

我正在使用下面的代码来恢复类对象:

BOOL CAppModule::InitInstance()
{   
    // Increment usage count
    if (_patlmodule != NULL)
    {
        _patlmodule->Lock();
        HRESULT hr = ::CoResumeClassObjects();  //Fails here
        if (FAILED(hr))
        {
            ASSERT_NOT_REACHED();
            if (hr == CO_E_WRONG_SERVER_IDENTITY)
            {
                gNTEventLog.LogHR(_T("Failed to resume class objects (registered as a service?)"), hr);
            }
            else
            {

                gNTEventLog.LogHR(_T("Failed to resume class objects"), hr);
            }
            return FALSE;
        }

    }

    return TRUE;
}

问题陈述: 重要的是,我想在 Windows Server 2012 R2 机器上运行此代码,其中方法 ::CoResumeClassObjects() 失败。这段代码在 Windows Server 2008 机器上运行良好。

请建议我 server2012 框是否与 ::CoResumeClassObjects() 方法有关。

此外,我正在创建一个单独的本地用户(这是应用程序要求),用于将 exe 注册为代码中的服务并负责启动/停止服务。win server 2012 有问题吗?

任何帮助将不胜感激......</p>

4

0 回答 0