Der folgende Code stammt aus der folgenden Seite:
http://www.vincenzo.net/isxkb/index.php?title=Service_-_Functions_to_Start%2C_Stop%2C_Install%2C_Remove_a_Service
Allerdings habe ich eine kleine Korrektur anwenden musste, damit es funktioniert.
Bitte beachte, dass ich ursprünglich diese Antwort geschrieben im Jahr 2010. Den Code auf die Seite oben wurde im Jahr 2011 aktualisiert, so könnte es einen Besuch wert sein.
Ich verwende diesen Code in meinem Installer als #include
. Es ist kompiliert in Inno Setup ANSI.
Es kann für die Unicode-Version von Inno-Setup funktionieren, indem [email protected]
durch [email protected]
in allen external
Deklarationen ersetzt wird (danke JeroenWiertPluimers für das hinweisend).
Beachten Sie auch, dass die StartService
und StopService
nur einen Start senden/Stopp-Signal, aber warten Sie nicht für den Dienst in den Betrieb der gestoppten Zustand zu sein.Sie können Code erstellen, der darauf warten würde, dass der Dienst ausgeführt wird. Verwenden Sie dazu den Befehl IsServiceRunning
in Verbindung mit der Funktion Pascal Script Sleep()
. Oder einfach Sleep()
eine vordefinierte Anzahl von Sekunden.
Der Code implementiert diese Funktionen:
function IsServiceInstalled(ServiceName: string) : boolean;
function IsServiceRunning(ServiceName: string) : boolean;
function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
function RemoveService(ServiceName: string) : boolean;
function StartService(ServiceName: string) : boolean;
function StopService(ServiceName: string) : boolean;
function SetupService(service, port, comment: string) : boolean;
Der eigentliche Code:
type
SERVICE_STATUS = record
dwServiceType : cardinal;
dwCurrentState : cardinal;
dwControlsAccepted : cardinal;
dwWin32ExitCode : cardinal;
dwServiceSpecificExitCode : cardinal;
dwCheckPoint : cardinal;
dwWaitHint : cardinal;
end;
HANDLE = cardinal;
const
SERVICE_QUERY_CONFIG = $1;
SERVICE_CHANGE_CONFIG = $2;
SERVICE_QUERY_STATUS = $4;
SERVICE_START = $10;
SERVICE_STOP = $20;
SERVICE_ALL_ACCESS = $f01ff;
SC_MANAGER_ALL_ACCESS = $f003f;
SERVICE_WIN32_OWN_PROCESS = $10;
SERVICE_WIN32_SHARE_PROCESS = $20;
SERVICE_WIN32 = $30;
SERVICE_INTERACTIVE_PROCESS = $100;
SERVICE_BOOT_START = $0;
SERVICE_SYSTEM_START = $1;
SERVICE_AUTO_START = $2;
SERVICE_DEMAND_START = $3;
SERVICE_DISABLED = $4;
SERVICE_DELETE = $10000;
SERVICE_CONTROL_STOP = $1;
SERVICE_CONTROL_PAUSE = $2;
SERVICE_CONTROL_CONTINUE = $3;
SERVICE_CONTROL_INTERROGATE = $4;
SERVICE_STOPPED = $1;
SERVICE_START_PENDING = $2;
SERVICE_STOP_PENDING = $3;
SERVICE_RUNNING = $4;
SERVICE_CONTINUE_PENDING = $5;
SERVICE_PAUSE_PENDING = $6;
SERVICE_PAUSED = $7;
{ nt based service utilities }
function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE;
external '[email protected] stdcall';
function OpenService(hSCManager :HANDLE;lpServiceName: string; dwDesiredAccess :cardinal): HANDLE;
external '[email protected] stdcall';
function CloseServiceHandle(hSCObject :HANDLE): boolean;
external '[email protected] stdcall';
function CreateService(hSCManager :HANDLE;lpServiceName, lpDisplayName: string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl: cardinal;lpBinaryPathName,lpLoadOrderGroup: String; lpdwTagId : cardinal;lpDependencies,lpServiceStartName,lpPassword :string): cardinal;
external '[email protected] stdcall';
function DeleteService(hService :HANDLE): boolean;
external '[email protected] stdcall';
function StartNTService(hService :HANDLE;dwNumServiceArgs : cardinal;lpServiceArgVectors : cardinal) : boolean;
external '[email protected] stdcall';
function ControlService(hService :HANDLE; dwControl :cardinal;var ServiceStatus :SERVICE_STATUS) : boolean;
external '[email protected] stdcall';
function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean;
external '[email protected] stdcall';
function QueryServiceStatusEx(hService :HANDLE;ServiceStatus :SERVICE_STATUS) : boolean;
external '[email protected] stdcall';
function GetLastError() : cardinal;
external '[email protected] stdcall';
function OpenServiceManager() : HANDLE;
begin
if UsingWinNT() = true then begin
Result := OpenSCManager('','',SC_MANAGER_ALL_ACCESS);
if Result = 0 then
MsgBox('the servicemanager is not available', mbError, MB_OK)
end
else begin
MsgBox('only nt based systems support services', mbError, MB_OK)
Result := 0;
end
end;
function IsServiceInstalled(ServiceName: string) : boolean;
var
hSCM : HANDLE;
hService: HANDLE;
begin
hSCM := OpenServiceManager();
Result := false;
if hSCM <> 0 then begin
hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_CONFIG);
if hService <> 0 then begin
Result := true;
CloseServiceHandle(hService)
end;
CloseServiceHandle(hSCM)
end
end;
function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
var
hSCM : HANDLE;
hService: HANDLE;
begin
hSCM := OpenServiceManager();
Result := false;
if hSCM <> 0 then begin
hService := CreateService(hSCM,ServiceName,DisplayName,SERVICE_ALL_ACCESS,ServiceType,StartType,0,FileName,'',0,'','','');
if hService <> 0 then begin
Result := true;
{ Win2K & WinXP supports additional description text for services }
if Description<> '' then
RegWriteStringValue(HKLM,'System\CurrentControlSet\Services\' + ServiceName,'Description',Description);
CloseServiceHandle(hService)
end;
CloseServiceHandle(hSCM)
end
end;
function RemoveService(ServiceName: string) : boolean;
var
hSCM : HANDLE;
hService: HANDLE;
begin
hSCM := OpenServiceManager();
Result := false;
if hSCM <> 0 then begin
hService := OpenService(hSCM,ServiceName,SERVICE_DELETE);
if hService <> 0 then begin
Result := DeleteService(hService);
CloseServiceHandle(hService)
end;
CloseServiceHandle(hSCM)
end
end;
function StartService(ServiceName: string) : boolean;
var
hSCM : HANDLE;
hService: HANDLE;
begin
hSCM := OpenServiceManager();
Result := false;
if hSCM <> 0 then begin
hService := OpenService(hSCM,ServiceName,SERVICE_START);
if hService <> 0 then begin
Result := StartNTService(hService,0,0);
CloseServiceHandle(hService)
end;
CloseServiceHandle(hSCM)
end;
end;
function StopService(ServiceName: string) : boolean;
var
hSCM : HANDLE;
hService: HANDLE;
Status : SERVICE_STATUS;
begin
hSCM := OpenServiceManager();
Result := false;
if hSCM <> 0 then begin
hService := OpenService(hSCM,ServiceName,SERVICE_STOP);
if hService <> 0 then begin
Result := ControlService(hService,SERVICE_CONTROL_STOP,Status);
CloseServiceHandle(hService)
end;
CloseServiceHandle(hSCM)
end;
end;
function IsServiceRunning(ServiceName: string) : boolean;
var
hSCM : HANDLE;
hService: HANDLE;
Status : SERVICE_STATUS;
begin
hSCM := OpenServiceManager();
Result := false;
if hSCM <> 0 then begin
hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_STATUS);
if hService <> 0 then begin
if QueryServiceStatus(hService,Status) then begin
Result :=(Status.dwCurrentState = SERVICE_RUNNING)
end;
CloseServiceHandle(hService)
end;
CloseServiceHandle(hSCM)
end
end;
Ich habe einen Code geerbt, der genau wie Ihre Antwort aussieht. Sie haben weder die Quelle noch * ANSI * erwähnt, also brauchte ich eine Weile, um zu erkennen, dass der 'ERROR_INVALID_NAME' alias 123 (0x7B) -Fehler von' OpenSCManager' durch Ersetzen von 'A @' mit 'W @' behoben werden konnte 'externe' Deklarationen, da ich Inno Setup * Unicode * ausgeführt habe. –