2011-07-01 21 views
2

Inno SetupのPascalスクリプト言語を使用してサービスの失敗アクションを設定しようとしています。 "アドレスでのアクセス違反..."エラーが発生しました。言語がポインタをサポートしていないため不可能だと思われます。何か案は?ここでは、コードスニペットは次のとおりです。Inno Setup構造体へのポインタを持つWindows DLL関数呼び出し

type 
    TScAction = record 
    aType1 : Longword; 
    Delay1 : Longword; 
    aType2 : Longword; 
    Delay2 : Longword; 
    aType3 : Longword; 
    Delay3 : Longword; 
    end; 

type 
    TServiceFailureActionsA = record 
    dwResetPeriod : DWORD; 
    pRebootMsg : String; 
    pCommand : String; 
    cActions : DWORD; 
    saActions : TScAction; 
    end; 

function ChangeServiceConfig2(hService: Longword; dwInfoLevel: Longword; lpInfo: TServiceFailureActionsA): BOOL; 
    external '[email protected] stdcall'; 

procedure SimpleChangeServiceConfig(AService: string); 
var 
    SCMHandle: Longword; 
    ServiceHandle: Longword; 
    sfActions: TServiceFailureActionsA; 
    sActions: TScAction; 
begin 
    try 
    SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS); 
    if SCMHandle = 0 then 
     RaiseException('[email protected]: ' + AService + ' ' + 
     SysErrorMessage(DLLGetLastError)); 
    try 
     ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS); 
     if ServiceHandle = 0 then 
     RaiseException('[email protected]: ' + AService + ' ' + 
      SysErrorMessage(DLLGetLastError)); 
     try 

     sActions.aType1 := SC_ACTION_RESTART; 
     sActions.Delay1 := 60000;    // First.nDelay: in milliseconds, MMC displayed in minutes 
     sActions.aType2 := SC_ACTION_RESTART; 
     sActions.Delay2 := 60000; 
     sActions.aType3 := SC_ACTION_RESTART; 
     sActions.Delay3 := 60000; 

     sfActions.dwResetPeriod := 1;   // in seconds, MMC displayes in days 
     //sfActions.pRebootMsg := null;   // reboot message unchanged 
     //sfActions.pCommand := null;   // command line unchanged 
     sfActions.cActions := 3;    // first, second and subsequent failures 
     sfActions.saActions := sActions;   

     if not ChangeServiceConfig2(
      ServiceHandle,      // handle to service 
      SERVICE_CONFIG_FAILURE_ACTIONS,  // change: description 
      sfActions)       // new description 
     then 
      RaiseException('[email protected]: ' + AService + ' ' + 
      SysErrorMessage(DLLGetLastError)); 
     finally 
     if ServiceHandle <> 0 then 
      CloseServiceHandle(ServiceHandle); 
     end; 
    finally 
     if SCMHandle <> 0 then 
     CloseServiceHandle(SCMHandle); 
    end; 
    except 
    ShowExceptionMessage; 
    end; 
end; 
+0

エラーはどこで発生しますか? (Innoにはデバッガが組み込まれています) アクセス違反はもちろん、外部コードを呼び出すと可能です。 – Deanna

+0

これは、ChangeServiceConfig2が –

+1

と呼ばれているときに発生します。渡す値は正確に何ですか?私たちは精神的なものではありません、あなたは私たちに何か情報を伝える必要があります。 – Deanna

答えて

0

は、それが機能する構造体へのポインタを渡すことだと指定するlpInfoパラメータに宣言でvarキーワードを使用してみてください。

+0

これはあなたのためにできましたか?その場合は、合格とマークしてください。 – Deanna

4

スクリプトに2つの問題があります。 Deannaのように、lpInfoパラメータの宣言でvarキーワードを使用する必要があることが示唆されました。

また、TScActionタイプを2つの要素を持つ配列に変更する必要があります。

Inno Setupスクリプトに含めることができるスクリプトです。

const 
    SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3; //The lpInfo parameter is a pointer to a SERVICE_DELAYED_AUTO_START_INFO structure. 
               //Windows Server 2003 and Windows XP: This value is not supported. 
    SERVICE_CONFIG_DESCRIPTION    = 1; //The lpInfo parameter is a pointer to a SERVICE_DESCRIPTION structure. 
    SERVICE_CONFIG_FAILURE_ACTIONS   = 2; //The lpInfo parameter is a pointer to a SERVICE_FAILURE_ACTIONS structure. 
               //If the service controller handles the SC_ACTION_REBOOT action, the caller must have 
               // the SE_SHUTDOWN_NAME privilege. For more information, see Running with Special Privileges. 
    SERVICE_CONFIG_FAILURE_ACTIONS_FLAG  = 4; //The lpInfo parameter is a pointer to a SERVICE_FAILURE_ACTIONS_FLAG structure. 
               //Windows Server 2003 and Windows XP: This value is not supported. 
    SERVICE_CONFIG_PREFERRED_NODE   = 9; //The lpInfo parameter is a pointer to a SERVICE_PREFERRED_NODE_INFO structure. 
               //Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This value is not supported. 
    SERVICE_CONFIG_PRESHUTDOWN_INFO   = 7; //The lpInfo parameter is a pointer to a SERVICE_PRESHUTDOWN_INFO structure. 
               //Windows Server 2003 and Windows XP: This value is not supported. 
    SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 6; //The lpInfo parameter is a pointer to a SERVICE_REQUIRED_PRIVILEGES_INFO structure. 
               //Windows Server 2003 and Windows XP: This value is not supported. 
    SERVICE_CONFIG_SERVICE_SID_INFO   = 5; //The lpInfo parameter is a pointer to a SERVICE_SID_INFO structure. 
    SERVICE_CONFIG_TRIGGER_INFO    = 8; //The lpInfo parameter is a pointer to a SERVICE_TRIGGER_INFO structure. 
               //This value is not supported by the ANSI version of ChangeServiceConfig2. 
               //Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This value is not supported until Windows Server 2008 R2. 

    SC_ACTION_NONE  = 0; // No action. 
    SC_ACTION_REBOOT  = 2; // Reboot the computer. 
    SC_ACTION_RESTART  = 1; // Restart the service. 
    SC_ACTION_RUN_COMMAND = 3; // Run a command. 

type 
    TScAction = record 
    aType1 : Longword; 
    Delay1 : Longword; 
    end; 

type 
    TServiceFailureActionsA = record 
    dwResetPeriod : DWORD; 
    pRebootMsg : String; 
    pCommand : String; 
    cActions : DWORD; 
    saActions : array of TScAction; 
    end; 

function ChangeServiceConfig2(
    hService: Longword; 
    dwInfoLevel: Longword; 
    var lpInfo: TServiceFailureActionsA): BOOL; 
    external '[email protected] stdcall'; 


procedure SimpleChangeServiceConfig(AService: string); 
var 
    SCMHandle: Longword; 
    ServiceHandle: Longword; 
    sfActions: TServiceFailureActionsA; 
    sActions: array of TScAction; 
begin 
    SetArrayLength(sActions ,3); 
    try 
    SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS); 
    if SCMHandle = 0 then 
     RaiseException('[email protected]: ' + AService + ' ' + 
     SysErrorMessage(DLLGetLastError)); 
    try 
     ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS); 
     if ServiceHandle = 0 then 
     RaiseException('[email protected]: ' + AService + ' ' + 
      SysErrorMessage(DLLGetLastError)); 
     try 

     sActions[0].aType1 := SC_ACTION_RESTART; 
     sActions[0].Delay1 := 60000;    // First.nDelay: in milliseconds, MMC displayed in minutes 
     sActions[1].aType1 := SC_ACTION_RESTART; 
     sActions[1].Delay1 := 60000; 
     sActions[2].aType1 := SC_ACTION_NONE; 
     sActions[2].Delay1 := 60000; 

     sfActions.dwResetPeriod := 1;   // in seconds, MMC displayes in days 
     //sfActions.pRebootMsg := null;   // reboot message unchanged 
     //sfActions.pCommand := null;   // command line unchanged 
     sfActions.cActions := 3;    // first, second and subsequent failures 
     sfActions.saActions := sActions;   

     if not ChangeServiceConfig2(
      ServiceHandle,    // handle to service 
      SERVICE_CONFIG_FAILURE_ACTIONS, // change: description 
      sfActions)  // new description 
     then 
      RaiseException('[email protected]: ' + AService + ' ' + 
      SysErrorMessage(DLLGetLastError)); 
     finally 
     if ServiceHandle <> 0 then 
      CloseServiceHandle(ServiceHandle); 
     end; 
    finally 
     if SCMHandle <> 0 then 
     CloseServiceHandle(SCMHandle); 
    end; 
    except 
    ShowExceptionMessage; 
    end; 
end;  
関連する問題