none
Windows server 2008的Service Control Manager中启动的某进程创建WLBS子进程操作远端cluster node 失败 RRS feed

  • 问题

  • 其实我想提的大类是服务器开发,算了,不提这个分类了,还是请大家帮忙看看我的疑惑吧。

    OS:Windows server 2008 / Windows server 2008 r2
    IDE:Visual C++ 2005

    我有一个程序A,Win32的程序,Service的形式,在Windows的Service Control Manager中启动。A中调用CreateProcess创建WLBS命令去启动和停止远程的cluster节点。但是无论如何也不能启动或者停止远程节点,可以启动或者停止本地节点。 另外,手动执行wlbs命令是可以启动远程节点的。wlbs服务没有设置密码。

    关键代码如下:

    服务的安装:

    BOOL CNTService::Install()
    {
        // Open the Service Control Manager
        SC_HANDLE hSCM = ::OpenSCManager(NULL, // local machine
                                         NULL, // ServicesActive database
                                         SC_MANAGER_ALL_ACCESS); // full access
        if (!hSCM) return FALSE;
    
        // Get the executable file path
        char szFilePath[_MAX_PATH];
        ::GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
    
        // Create the service
        SC_HANDLE hService = ::CreateService(hSCM,
                                             m_szServiceName,
                                             m_szServiceName,
                                             SERVICE_ALL_ACCESS,
                                             SERVICE_WIN32_OWN_PROCESS |SERVICE_INTERACTIVE_PROCESS,
                                             SERVICE_DEMAND_START,        // start condition
                                             SERVICE_ERROR_NORMAL,
                                             szFilePath,
                                             NULL,
                                             NULL,
                                             NULL,
                                             NULL,
                                             NULL);
        if (!hService) {
          DWORD dwErr = GetLastError();
          switch(dwErr)
          {
          case ERROR_ACCESS_DENIED:
            break;
          case ERROR_CIRCULAR_DEPENDENCY:
            break;
          case ERROR_DUP_NAME:
            break;
          case ERROR_INVALID_HANDLE:
            break;
          case ERROR_INVALID_NAME:
            break;
          case ERROR_INVALID_PARAMETER:
            break;
          case ERROR_INVALID_SERVICE_ACCOUNT:
            break;
          case ERROR_SERVICE_EXISTS:
            break;
          default:
            break;
          }
          NvUtility::DisplayError("CreateService");
          SetLastError(dwErr);
          ::CloseServiceHandle(hSCM);
          return FALSE;
        }
    
        // make registry entries to support logging messages
        // Add the source name as a subkey under the Application
        // key in the EventLog service portion of the registry.
        char szKey[256];
        HKEY hKey = NULL;
        strcpy(szKey, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");
        strcat(szKey, m_szServiceName);
        if (::RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &hKey) != ERROR_SUCCESS) {
            ::CloseServiceHandle(hService);
            ::CloseServiceHandle(hSCM);
            return FALSE;
        }
    
        // Add the Event ID message-file name to the 'EventMessageFile' subkey.
        ::RegSetValueEx(hKey,
                        "EventMessageFile",
                        0,
                        REG_EXPAND_SZ, 
                        (CONST BYTE*)szFilePath,
                        strlen(szFilePath) + 1);     
    
        // Set the supported types flags.
        DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
        ::RegSetValueEx(hKey,
                        "TypesSupported",
                        0,
                        REG_DWORD,
                        (CONST BYTE*)&dwData,
                         sizeof(DWORD));
        ::RegCloseKey(hKey);
    
        LogEvent(EVENTLOG_INFORMATION_TYPE, EVMSG_INSTALLED, m_szServiceName);
    
        // tidy up
        ::CloseServiceHandle(hService);
        ::CloseServiceHandle(hSCM);
        return TRUE;
    }

    wlbs子进程的创建:

    result  NvCs::ExecWlbsCommand(const TCHAR *cmd)
    {
        result res = errUnknown;
        PROCESS_INFORMATION pi = {NULL};
        STARTUPINFO si = {sizeof(si)};
        ZeroMemory(&pi, sizeof(pi));
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
    
        #if defined NDEBUG
        si.wShowWindow = SW_HIDE;
        #else
        si.wShowWindow = SW_SHOWNORMAL;
        #endif
    
        // wlbs.exe is in the system directory
        TCHAR cmdLine[MAX_PATH] = TEXT("");
        UINT cb = ::GetSystemDirectory(cmdLine, sizeof cmdLine);
        // This path does not end with a backslash unless the system directory is the root directory
        if ((cb > 3) && (cb < sizeof cmdLine)) _tcscat(cmdLine, TEXT("\\"));
    
        _tcscat(cmdLine, "WLBS.EXE ");
        _tcscat(cmdLine, cmd);
    
        if (::CreateProcess(NULL, cmdLine, 0, 0, FALSE, CREATE_NEW_CONSOLE, 0, 0, &si, &pi))
        {
            DWORD dwWait = ::WaitForSingleObject(pi.hProcess, wlbsTimeout);
            if (WAIT_OBJECT_0 == dwWait)
            {
                DWORD wlbsExitCode = 0XFFFFFFFF;
                if (::GetExitCodeProcess(pi.hProcess, &wlbsExitCode) && (1 == wlbsExitCode))
                    res = success;
                DebugMsg("wlbsExitCode = %d\n", wlbsExitCode);
            } else {
                res = errUnexpected;
                DebugMsg("Trouble while executing WLBS command");
            }
            ::CloseHandle(pi.hProcess);
            ::CloseHandle(pi.hThread);
        }
    
      if(m_b_simul_wlbs)
        res = success;
      DebugMsg("ExecWlbsCommand(%s), res = %d\n", cmdLine, res);
        return res;
    }
    不好意思因为我没有分数,所以给不了分,如果我有肯定都给了。问题比较急。

    • 已编辑 [Richard] 2014年7月8日 6:09 补充说明
    2014年7月8日 6:05

答案

全部回复