gpt4 book ai didi

pointers - Inno Setup Windows DLL 函数调用,带有指向结构的指针

转载 作者:行者123 更新时间:2023-12-02 22:04:55 29 4
gpt4 key购买 nike

我正在尝试使用 Inno Setup 的 Pascal 脚本语言来设置服务的失败操作。我收到经典的“地址访问冲突...”错误。似乎这是不可能的,因为该语言不支持指针。有任何想法吗?这是代码片段:

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 'ChangeServiceConfig2A@advapi32.dll 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('SimpleChangeServiceConfig@OpenSCManager: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
try
ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);
if ServiceHandle = 0 then
RaiseException('SimpleChangeServiceConfig@OpenService: ' + 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('SimpleChangeServiceConfig@ChangeServiceConfig2: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
finally
if ServiceHandle <> 0 then
CloseServiceHandle(ServiceHandle);
end;
finally
if SCMHandle <> 0 then
CloseServiceHandle(SCMHandle);
end;
except
ShowExceptionMessage;
end;
end;

最佳答案

您的脚本中有两个问题。就像 Deanna 建议的那样,您必须在 lpInfo 参数的声明中使用 var 关键字。

您还需要将 TScAction 类型更改为包含两个元素的数组。

这是我的脚本,您可以将其包含在 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 'ChangeServiceConfig2A@advapi32.dll 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('SimpleChangeServiceConfig@OpenSCManager: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
try
ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);
if ServiceHandle = 0 then
RaiseException('SimpleChangeServiceConfig@OpenService: ' + 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('SimpleChangeServiceConfig@ChangeServiceConfig2: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
finally
if ServiceHandle <> 0 then
CloseServiceHandle(ServiceHandle);
end;
finally
if SCMHandle <> 0 then
CloseServiceHandle(SCMHandle);
end;
except
ShowExceptionMessage;
end;
end;

关于pointers - Inno Setup Windows DLL 函数调用,带有指向结构的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6545658/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com