0

Windows の ChangeServiceConfig2 API を使用して、サービスの説明を変更しています。Windows 98 では同じ API がサポートされていないため、私は LoadLibraray と GetProcAddress を使用して、exe での API の静的リンクを防止しました。詳細については、コードを参照してください。

typedef BOOL  (*ChgSvcDesc) (SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo);

eBool ServiceConfigNT::Install(IN tServiceDesc * pServiceDesc){


    SC_HANDLE           hservice;
    SC_HANDLE           hservicemgr;
    SERVICE_DESCRIPTION desc;
    ULong             starttype;
    HMODULE           hmod;
    ChgSvcDesc        fpsvcdesc;

// Opens the Service Control Manager
hservicemgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!hservicemgr){
    vPrepareError(_TEXT("Failed to open service control manager!!"));
    goto err;
}

// Set start method of service.
starttype   = (pServiceDesc->uAutoStart  == TRUE)? SERVICE_AUTO_START : SERVICE_DEMAND_START;

// Create the service
hservice =  CreateService(hservicemgr, vServiceName, pServiceDesc->uDisplayName, SERVICE_ALL_ACCESS, 
                pServiceDesc->uServiceType, starttype, SERVICE_ERROR_NORMAL,pServiceDesc->uExePath,
                NULL, NULL, NULL, NULL, NULL);

if(!hservice) {
    vPrepareError(_TEXT("Failed to create service.!!"));
    goto err;        
}

// Set the description string
if(pServiceDesc->uServiceDescription && *pServiceDesc->uServiceDescription) {     
    desc.lpDescription = pServiceDesc->uServiceDescription;
    // This cannot be executed since it is not supported in Win98 and ME OS
    //(Void)ChangeServiceConfig2 (hservice, SERVICE_CONFIG_DESCRIPTION, &desc);
    hmod = LoadLibrary(_TEXT("Advapi32.dll"));
    if(hmod) {
          // _UNICODE macro is set, hence im using the "W" version of the api
          fpsvcdesc = (ChgSvcDesc)GetProcAddress(hmod, "ChangeServiceConfig2W");      
          if(fpsvcdesc)
               // On execution of the below statement, I get the error handle is invalid
               fpsvcdesc(hservice, SERVICE_CONFIG_DESCRIPTION, &desc);
}

CloseServiceHandle(hservice);
CloseServiceHandle(hservicemgr);    
return TRUE;

err:
    if(hservicemgr) 
       CloseServiceHandle(hservicemgr);
return FALSE;
}

ハンドルが無効なエラーになる理由を見つけるために、コードを何度もデバッグしましたか? API を直接呼び出すと、サービスの説明が変更されますが、関数ポインタを使用するとエラーが発生します。

API が SCM のサービス ハンドルに何かを書き込んでいると思いますが、その理由はわかりません。

誰かがこれで私を助けることができますか?

4

1 に答える 1

2

関数ポインタは、呼び出し規約が指定されていない状態で宣言されています。デフォルトの呼び出し規約は__cdeclです。しかし、WindowsAPI関数は__stdcallです。関数ポインタ型に呼び出し規約を追加する必要があります。

typedef BOOL (__stdcall *ChgSvcDesc) (SC_HANDLE hService, 
    DWORD dwInfoLevel, LPVOID lpInfo);
于 2012-12-20T09:09:30.513 に答える