特定の Windows サービスの「ログオン」パラメータを取得する方法を教えてください。アップグレード プロジェクトでサービスを再登録する必要があり、最初にセットアップされたのと同じアカウントで実行する必要があります。返された構造に lpServiceStartName を含む advapi32.dll で QueryServiceConfig を見つけましたが、Inno Setup から機能させることができません。
1694 次
2 に答える
5
QueryServiceConfig
InnoSetup スクリプトから関数を使用することはできません。この関数を使用するには、ヒープからバッファーを割り当てる必要がありますが、InnoSetup ではそれは不可能です。代わりに、WMI を使用できます。具体的には、要求したプロパティWin32_Service
を含む WMI クラスを使用できます。StartName
InnoSetup スクリプトでは、次のようになります。
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
[Code]
function GetServiceStartName(const AServiceName: string): string;
var
WbemLocator: Variant;
WbemServices: Variant;
WbemObject: Variant;
WbemObjectSet: Variant;
begin;
Result := '';
WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
WbemServices := WbemLocator.ConnectServer('localhost', 'root\CIMV2');
WbemObjectSet := WbemServices.ExecQuery('SELECT * FROM Win32_Service ' +
'WHERE Name = "' + AServiceName + '"');
if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then
begin
WbemObject := WbemObjectSet.Item('Win32_Service.Name="' +
AServiceName + '"');
if not VarIsNull(WbemObject) then
Result := WbemObject.StartName;
end;
end;
procedure SvcStartNameTestButtonClick(Sender: TObject);
begin
MsgBox(GetServiceStartName('Netlogon'), mbInformation, MB_OK);
end;
procedure InitializeWizard;
var
SvcStartNameTestButton: TNewButton;
begin
SvcStartNameTestButton := TNewButton.Create(WizardForm);
SvcStartNameTestButton.Parent := WizardForm;
SvcStartNameTestButton.Left := 8;
SvcStartNameTestButton.Top := WizardForm.ClientHeight -
SvcStartNameTestButton.Height - 8;
SvcStartNameTestButton.Width := 175;
SvcStartNameTestButton.Caption := 'Get service start name...';
SvcStartNameTestButton.OnClick := @SvcStartNameTestButtonClick;
end;
外部ライブラリを作成し、それをスクリプトから呼び出す方が、はるかに簡単 (そしておそらくより高速) です。Delphi または Lazarus を使用している場合は、関数を使用して、要求したメンバーQueryServiceConfig
を取得する次の関数を使用できます。lpServiceStartName
function GetServiceStartName(const AServiceName: string): string;
var
BufferSize: DWORD;
BytesNeeded: DWORD;
ServiceHandle: SC_HANDLE;
ServiceManager: SC_HANDLE;
ServiceConfig: PQueryServiceConfig;
begin
Result := '';
ServiceManager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
if ServiceManager <> 0 then
try
ServiceHandle := OpenService(ServiceManager, PChar(AServiceName),
SERVICE_QUERY_CONFIG);
if ServiceHandle <> 0 then
try
if not QueryServiceConfig(ServiceHandle, nil, 0, BufferSize) and
(GetLastError = ERROR_INSUFFICIENT_BUFFER) then
begin
ServiceConfig := AllocMem(BufferSize);
try
if QueryServiceConfig(ServiceHandle, ServiceConfig, BufferSize,
BytesNeeded)
then
Result := ServiceConfig^.lpServiceStartName;
finally
FreeMem(ServiceConfig);
end;
end;
finally
CloseServiceHandle(ServiceHandle);
end;
finally
CloseServiceHandle(ServiceManager);
end;
end;
于 2012-10-23T15:11:14.183 に答える
1
外部ライブラリをリンクするという考えが気に入らなかったので、最終的にこの方法で問題を解決しました:
function GetServiceLogonAs():string;
var
res : Integer;
TmpFileName, FileContent: String;
begin
TmpFileName := ExpandConstant('{tmp}') + '\Service_Info.txt';
Exec('cmd.exe', '/C sc qc "MyServiceName" > "' + TmpFileName + '"', '', SW_HIDE, ewWaitUntilTerminated, res);
if LoadStringFromFile(TmpFileName, FileContent) then
begin
Result := Trim(Copy(FileContent,Pos('SERVICE_START_NAME', FileContent)+20,Length(FileContent)-(Pos('SERVICE_START_NAME', FileContent)+21)));
DeleteFile(TmpFileName);
end
else
begin
ShowErrorMsg('Error calling: GetServiceLogonAs(" + MYSERVICE + ")', res);
Result := '';
end;
end;
于 2012-10-25T13:09:12.573 に答える