2
0
Unknown 7 жил өмнө
parent
commit
c983c654b5
1 өөрчлөгдсөн 235 нэмэгдсэн , 0 устгасан
  1. 235 0
      Quick.Service.pas

+ 235 - 0
Quick.Service.pas

@@ -0,0 +1,235 @@
+{ ***************************************************************************
+
+  Copyright (c) 2016-2018 Kike Pérez
+
+  Unit        : Quick.Service
+  Description : Service functions
+  Author      : Kike Pérez
+  Version     : 1.0
+  Created     : 14/07/2017
+  Modified    : 14/03/2018
+
+  This file is part of QuickLib: https://github.com/exilon/QuickLib
+
+ ***************************************************************************
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+ *************************************************************************** }
+unit Quick.Service;
+
+interface
+
+uses
+  System.SysUtils,
+  Winapi.Windows,
+  Winapi.WinSvc,
+  Winapi.Messages,
+  System.IOUtils,
+  Quick.Commons,
+  Quick.Process;
+
+type
+  TServiceState = (ssUnknow = -1,
+                   ssStopped = SERVICE_STOPPED,
+                   ssStartPending = SERVICE_START_PENDING,
+                   ssStopPending = SERVICE_STOP_PENDING,
+                   ssRunning = SERVICE_RUNNING,
+                   ssContinuePending = SERVICE_CONTINUE_PENDING,
+                   ssPausePending = SERVICE_PAUSE_PENDING,
+                   ssPaused = SERVICE_PAUSED);
+
+  function ServiceIsPresent(const aMachine, aServiceName : string): Boolean;
+  function GetServicePath : string;
+  function GetServiceState(const aServer, aServiceName : string) : TServiceState;
+  function ServiceStart(const aMachine, aServiceName : string) : Boolean;
+  function ServiceStop(const aMachine, aServiceName : string ) : Boolean;
+  function ServiceUninstall(const aServiceName : string): Boolean;
+  function DeleteServiceEx(svcName : string) : Boolean;
+
+implementation
+
+function ServiceIsPresent(const aMachine, aServiceName : string): Boolean;
+var
+  smanHnd : SC_Handle;
+  svchnd : SC_Handle;
+begin
+  Result := False;
+  smanHnd := OpenSCManager(PChar(aMachine), nil, SC_MANAGER_CONNECT);
+  if (smanHnd > 0) then
+  begin
+    try
+      svcHnd := OpenService(smanHnd, PChar(aServiceName), SERVICE_QUERY_STATUS);
+      if svcHnd > 0 then
+      begin
+        Result := True;
+        CloseServiceHandle(svchnd);
+      end;
+    finally
+      CloseServiceHandle(smanHnd);
+    end;
+  end
+  else raise Exception.CreateFmt('GetServiceState failed: %s',[GetLastOSError]);
+end;
+
+function GetServicePath : string;
+var
+  filename : array[0..255] of Char;
+begin
+   GetModuleFileName(hInstance,filename,255);
+   Result := TPath.GetDirectoryName(filename);
+end;
+
+function GetServiceState(const aServer, aServiceName : string) : TServiceState;
+var
+  svcStatus : TServiceStatus;
+  smanHnd : SC_Handle;
+  svcHnd : SC_Handle;
+begin
+  Result := TServiceState.ssUnknow;
+  smanHnd := OpenSCManager(PChar(aServer), Nil, SC_MANAGER_ALL_ACCESS);
+  if smanHnd > 0 then
+  begin
+    try
+      svcHnd := OpenService(smanHnd, PChar(aServiceName), SERVICE_ALL_ACCESS);
+      if svcHnd > 0 then
+      try
+        if not QueryServiceStatus(svcHnd,svcStatus) then raise Exception.CreateFmt('GetServiceState failed: %s',[GetLastOSError]);
+        Result := TServiceState(svcStatus.dwCurrentState);
+      finally
+        CloseServiceHandle(svcHnd);
+      end;
+    finally
+      CloseServiceHandle(smanHnd);
+    end;
+  end
+  else raise Exception.CreateFmt('GetServiceState failed: %s',[GetLastOSError]);
+end;
+
+function ServiceStart(const aMachine, aServiceName : string) : Boolean;
+var
+  smanHnd : SC_HANDLE;
+  svcHnd : SC_HANDLE;
+  svcStatus : TServiceStatus;
+  psTemp : PChar;
+  dwChkP : DWord;
+begin
+  svcStatus.dwCurrentState := 0;
+  smanHnd := OpenSCManager(PChar(aMachine),nil,SC_MANAGER_CONNECT);
+  if smanHnd > 0 then
+  begin
+    try
+      svcHnd := OpenService(smanHnd,PChar(aServiceName),SERVICE_START or SERVICE_QUERY_STATUS);
+      if svcHnd > 0 then
+      try
+        psTemp := nil;
+        if StartService(svcHnd,0,psTemp) then
+        begin
+          if QueryServiceStatus(svcHnd,svcStatus) then
+          begin
+            while svcStatus.dwCurrentState <> SERVICE_RUNNING do
+            begin
+              dwChkP := svcStatus.dwCheckPoint;
+              Sleep(svcStatus.dwWaitHint);
+              if not QueryServiceStatus(svcHnd,svcStatus) then Break;
+
+              if svcStatus.dwCheckPoint < dwChkP then Break;
+            end;
+          end;
+        end;
+      finally
+        CloseServiceHandle(svcHnd);
+      end;
+    finally
+      CloseServiceHandle(smanHnd);
+    end;
+  end
+  else raise Exception.CreateFmt('GetServiceState failed: %s',[GetLastOSError]);
+  Result := SERVICE_RUNNING = svcStatus.dwCurrentState;
+end;
+
+function ServiceStop(const aMachine, aServiceName : string ) : Boolean;
+var
+  smanHnd : SC_HANDLE;
+  svcHnd : SC_HANDLE;
+  svcStatus : TServiceStatus;
+  dwChkP : DWord;
+begin
+  smanHnd := OpenSCManager(PChar(aMachine),nil,SC_MANAGER_CONNECT);
+  if smanHnd > 0 then
+  try
+    svcHnd := OpenService(smanHnd,PChar(aServiceName),SERVICE_STOP or SERVICE_QUERY_STATUS);
+    if svcHnd > 0 then
+    try
+      if ControlService(svcHnd,SERVICE_CONTROL_STOP,svcStatus) then
+      begin
+        if QueryServiceStatus(svcHnd,svcStatus) then
+        begin
+          while svcStatus.dwCurrentState <> SERVICE_STOPPED do
+          begin
+            dwChkP := svcStatus.dwCheckPoint;
+            Sleep(svcStatus.dwWaitHint);
+            if not QueryServiceStatus(svcHnd,svcStatus) then Break;
+            if svcStatus.dwCheckPoint < dwChkP then Break;
+          end;
+        end;
+      end;
+    finally
+      CloseServiceHandle(svcHnd);
+    end;
+  finally
+    CloseServiceHandle(smanHnd);
+  end;
+  Result := SERVICE_STOPPED = svcStatus.dwCurrentState;
+end;
+
+function ServiceUninstall(const aServiceName : string): Boolean;
+var
+  smanHnd : SC_Handle;
+  svchnd : SC_Handle;
+  strMachineName: String;
+begin
+  strMachineName := 'localhost';
+  smanHnd := OpenSCManager(PChar(strMachineName), nil, SC_MANAGER_CONNECT);
+  if smanHnd > 0 then
+  begin
+    try
+      svchnd := OpenService(smanHnd, PChar(aServiceName), SERVICE_ALL_ACCESS or SERVICE_STOP);
+      if svchnd > 0 then
+      begin
+        try
+          Winapi.WinSVC.DeleteService(svchnd);
+          Result := True;
+        finally
+          CloseServiceHandle(svchnd);
+        end;
+      end
+      else if svchnd = 0 Then
+        Result := True
+      else Result := False;
+    finally
+      CloseServiceHandle(smanHnd);
+    end;
+  end;
+end;
+
+function DeleteServiceEx(svcName : string) : Boolean;
+begin
+  Result := False;
+  if ShellExecuteAndWait('open','sc','stop '+svcName,'',0,True) = 0 then
+  begin
+    Result := ShellExecuteAndWait('open','sc','delete '+svcName,'',0,True) = 0;
+  end;
+end;
+
+end.