前面四个参数相同,如果bWMI设为False使用命令行方式,加入域成功。如果bWMI设为True,加入域失败,vReturn返回0x00000A87。
请各位帮忙看看这个函数哪里有问题?
//加入域 
BOOL JoinDomain(CString sComputerName, CString sDomainName, CString sUserName, CString sPassword, BOOL bWMI) 

        BOOL bJoin = FALSE;         if (!bWMI) 
        { 
                //命令行方式 
                CString sParam, sRead; 
                CStdioFile hFile;                 
                int nItem = GetSetupItemIndex("域");                 sParam.Format("/c wmic computersystem where Name=\"%s\" call JoinDomainOrWorkgroup Name=\"%s\" UserName=\"%s\\%s\" Password=\"%s\" FJoinOptions=3 > \"%s\"", 
                        sComputerName, sDomainName, sDomainName, sUserName, sPassword, theApp.m_sRunDir + "\\wmic.txt"); 
                theApp.WriteLog("cmd /c wmic " + sParam); 
                LF::RunWait("cmd", sParam, theApp.m_sRunDir, SW_HIDE); 
                if (hFile.Open(theApp.m_sRunDir + "\\wmic.txt", CFile::modeRead|CFile::typeText)) 
                { 
                        while (hFile.ReadString(sRead)) 
                        { 
                                if (sRead.Find("ReturnValue =") >= 0) 
                                { 
                                        SetSetupLog(nItem, sRead); 
                                        if (sRead.Find("ReturnValue = 0;") >= 0) 
                                        { 
                                                bJoin = TRUE; 
                                                break; 
                                        } 
                                } 
                        } 
                        hFile.Close(); 
                } 
                ::DeleteFile(theApp.m_sRunDir + "\\wmic.txt"); 
        } 
        else 
        {         
                //WMI方法                 
                BSTR bstrPath; 
                IWbemLocator *pLocal = NULL; 
                IWbemServices *pService = NULL;         
                IWbemClassObject *pClass = NULL, *pInParam = NULL, *pOutParam = NULL, *pInstance = NULL; 
                COleVariant vName, vUserName, vPassword, vJoinOptions, vReturn; 
                ULONG ulReturn = 0;                 if (SUCCEEDED(::CoInitializeEx(0, COINIT_MULTITHREADED))) 
                { 
                        //这里设为RPC_C_AUTHN_LEVEL_DEFAULT,vReturn还是返回0x00000A87
                        if (SUCCEEDED(::CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL))) 
                        {         
                                if (SUCCEEDED(::CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLocal))) 
                                {         
                                        if (SUCCEEDED(pLocal->ConnectServer(L"root\\cimv2", NULL, NULL, NULL, 0, NULL, NULL, &pService))) 
                                        {         
                                                if (SUCCEEDED(::CoSetProxyBlanket(pService, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE))) 
                                                {         
                                                        if (SUCCEEDED(pService->GetObject(L"Win32_ComputerSystem", 0, NULL, &pClass, NULL))) 
                                                        { 
                                                                if (SUCCEEDED(pClass->GetMethod(L"JoinDomainOrWorkgroup", 0, &pInParam, NULL))) 
                                                                { 
                                                                        if (SUCCEEDED(pInParam->SpawnInstance(0, &pInstance))) 
                                                                        { 
                                                                                vName = sDomainName; 
                                                                                pInstance->Put(L"Name", 0, &vName, 0); 
                                                                                vPassword = sPassword; 
                                                                                pInstance->Put(L"Password", 0, &vPassword, 0);                                                                         
                                                                                vUserName = sDomainName + "\\" + sUserName; 
                                                                                pInstance->Put(L"UserName", 0, &vUserName, 0); 
                                                                                vJoinOptions.vt = VT_UINT; 
                                                                                vJoinOptions.uintVal = 3; 
                                                                                pInstance->Put(L"FJoinOptions", 0, &vJoinOptions, 0); 
                                                                                bstrPath = LF::FormatString("Win32_ComputerSystem.Name='%s'", sComputerName).AllocSysString(); 
                                                                                if (SUCCEEDED(pService->ExecMethod(bstrPath, L"JoinDomainOrWorkgroup", 0, NULL, pInstance, &pOutParam, NULL))) 
                                                                                { 
                                                                                    
                                                                                        if (SUCCEEDED(pOutParam->Get(L"ReturnValue", 0, &vReturn, NULL, 0))) 
                                                                                        {//vReturn返回0x00000A87
                                                                                                if (vReturn.vt == VT_UINT && vReturn.uintVal == 0) bJoin = TRUE; 
                                                                                        } 
                                                                                        pOutParam->Release();                                                                                 
                                                                                } 
                                                                                ::SysFreeString(bstrPath); 
                                                                                pInstance->Release(); 
                                                                        } 
                                                                        pInParam->Release(); 
                                                                } 
                                                                pClass->Release(); 
                                                        }                                                                 
                                                } 
                                                pService->Release(); 
                                        } 
                                        pLocal->Release(); 
                                }                         
                        } 
                        ::CoUninitialize(); 
                } 
        } 
        return bJoin;         

解决方案 »

  1.   

    JoinDomainOrWorkGroupMSDN上有段VB的代码,不知道有帮助没有?The following VBScript code example joins a computer to a domain and creates the computer's account in Active Directory. Const JOIN_DOMAIN             = 1
    Const ACCT_CREATE             = 2
    Const ACCT_DELETE             = 4
    Const WIN9X_UPGRADE           = 16
    Const DOMAIN_JOIN_IF_JOINED   = 32
    Const JOIN_UNSECURE           = 64
    Const MACHINE_PASSWORD_PASSED = 128
    Const DEFERRED_SPN_SET        = 256
    Const INSTALL_INVOCATION      = 262144
    strDomain   = "FABRIKAM"
    strPassword = "ls4k5ywA"
    strUser     = "shenalan"
    Set objNetwork = CreateObject("WScript.Network")
    strComputer = objNetwork.ComputerName
    Set objComputer = _
        GetObject("winmgmts:{impersonationLevel=Impersonate}!\\" & _
        strComputer & "\root\cimv2:Win32_ComputerSystem.Name='" _
        & strComputer & "'")
    ReturnValue = objComputer.JoinDomainOrWorkGroup(strDomain, _
        strPassword, _
        strDomain & "\" & strUser, _
        NULL, _
        JOIN_DOMAIN + ACCT_CREATE)
      

  2.   

    为什么不直接用NetJoinDomain,搞这复杂.
    NET_API_STATUS NetJoinDomain(
      __in  LPCWSTR lpServer,
      __in  LPCWSTR lpDomain,
      __in  LPCWSTR lpAccountOU,
      __in  LPCWSTR lpAccount,
      __in  LPCWSTR lpPassword,
      __in  DWORD fJoinOptions
    );
      

  3.   

    NetJoinDomain的确有用,谢谢zwfgdlc让我知道了一种新的方法,可是我问题还是没有解决,WMI方式为什么会报错?有谁可以帮忙看一下吗?
      

  4.   

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa392154(v=vs.85).aspx
      

  5.   

    MSDN上没有提到A87错误,再等一天,如果还是没人知道就结贴。