AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Delphi und Serviceanwendungen, demo?
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi und Serviceanwendungen, demo?

Ein Thema von Mavarik · begonnen am 5. Mai 2018 · letzter Beitrag vom 6. Mai 2018
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.142 Beiträge
 
Delphi 10.3 Rio
 
#1

Delphi und Serviceanwendungen, demo?

  Alt 5. Mai 2018, 08:19
Hallo Zusammen...

Hat jemand ein working demo um einen Service-Anwendung zu starten, stoppen und zu beenden.

Nicht mit NET START... Sondern per Token die Adminrechte holen und dann WinSVC?

Ich habe vor Jahren - da gab es noch keinen TeamViewer - "so etwas" als Service programmiert. Das hat jedoch alles auf JEDI-Zeugs aufgebaut, was ich in der neuen Anwendungen nicht verwenden möchte...

Vielleicht hat ja jemand so ein codeschnipsel...

Vorab Danke

Mavarik
  Mit Zitat antworten Zitat
Benutzerbild von timog
timog

Registriert seit: 26. Sep 2006
Ort: Landkreis Oldenburg (Oldb)
117 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

AW: Delphi und Serviceanwendungen, demo?

  Alt 5. Mai 2018, 08:58
Von Luckie und CalganX stammt da ein Post mit OpenSCManager/OpenService. Nutze den mit einem Admin-Manifest für das Starten, Beenden und die Statusabfrage für Services. Ist die API dahinter noch aktuell?
Timo
Real Programmers are surprised when the odometers in their cars don't turn from 99999 to 9999A.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.580 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Delphi und Serviceanwendungen, demo?

  Alt 5. Mai 2018, 09:17
Sondern per Token die Adminrechte holen und dann WinSVC?
Wir starten einfach die eigene Anwendung mit passenden Parametern und Adminaufforderung im Hintergrund. Das ist deutlich einfacher, zudem hatten wir mit der Out-Of-Process COM Variante schon Probleme auf manchen Systemen, vor allem mit Antivirenprogrammen. Deshalb sind wir wieder bei der einfachen, aber so gut wie immer funktionierenden, Variante gelandet.

Und dann könntest du einfach ganz normal Quelltext wie diesen nutzen, um den Dienst zu starten oder zu stoppen:
https://www.entwickler-ecke.de/topic...toppen_77.html

Auch wenn es deiner Anforderung nicht entspricht (benutzt net start, weil wie erwähnt die OOP-COM-Variante wieder ausgebaut ist) verlinke ich trotzdem mal ein Beispiel wie wir bei uns Dienste gestalten:
https://www.delphipraxis.net/1323261-post24.html
Diese kann man normal als Anwendung starten und bekommt dann eine GUI zum Installieren, Starten usw., natürlich mit Statusprüfung über die API. An den Stellen, wo wir extern net.exe benutzen kann natürlich auch einfach der verlinkte Quelltext eingesetzt werden.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
969 Beiträge
 
Delphi 6 Professional
 
#4

AW: Delphi und Serviceanwendungen, demo?

  Alt 5. Mai 2018, 13:43
Hmm..

hab hier ne Unit (weiß nicht mehr woher), jedoch ist die mit Delphi6 erstellt und würde wohl Überarbeitungen im Bezug auf PChar benötigen
Für die benötigten Admin-Rechte musst Du jedoch selber schauen

Ich verwende Sie zum Auflisten/Starten/Stoppen von Diensten...

Delphi-Quellcode:
unit UStartStopService;

interface

uses
  Windows, Classes, SysUtils;

function ServiceGetStatus(sMachine, sService : string ) : DWord;

function ServiceStart(sMachine, sService : string ) : boolean;
function ServiceStop(sMachine, sService : string ) : boolean;

function ServiceRunning(sMachine, sService : string ) : boolean;
{
// "alerter" service on \ComputerName was started take appropriate action here
if( ServiceStart('\ComputerName','alerter' ) )then begin
end;
// stop "alerter" service running on the local computer
if( ServiceStop('','alerter' ) )then begin
end;
}


function ServiceGetList(sMachine : string; dwServiceType, dwServiceState : DWord;
  slServicesList : TStrings ): boolean;
{
To get a list of all Windows services into a listbox named ListBox1:
ServiceGetList( '', SERVICE_WIN32, SERVICE_STATE_ALL, ListBox1.Items );
}


const
  // Service Types
  SERVICE_KERNEL_DRIVER = $00000001;
  SERVICE_FILE_SYSTEM_DRIVER = $00000002;
  SERVICE_ADAPTER = $00000004;
  SERVICE_RECOGNIZER_DRIVER = $00000008;

  SERVICE_DRIVER =
    (SERVICE_KERNEL_DRIVER or
     SERVICE_FILE_SYSTEM_DRIVER or
     SERVICE_RECOGNIZER_DRIVER);

  SERVICE_WIN32_OWN_PROCESS = $00000010;
  SERVICE_WIN32_SHARE_PROCESS = $00000020;
  SERVICE_WIN32 =
    (SERVICE_WIN32_OWN_PROCESS or
     SERVICE_WIN32_SHARE_PROCESS);

  SERVICE_INTERACTIVE_PROCESS = $00000100;

  SERVICE_TYPE_ALL =
    (SERVICE_WIN32 or
     SERVICE_ADAPTER or
     SERVICE_DRIVER or
     SERVICE_INTERACTIVE_PROCESS);

implementation

uses WinSvc;

//-------------------------------------
// get service status
// return status code if successful
// 0 if not
//
// return codes:
// SERVICE_STOPPED
// SERVICE_RUNNING
// SERVICE_PAUSED
//
// following return codes
// are used to indicate that
// the service is in the
// middle of getting to one
// of the above states:
// SERVICE_START_PENDING
// SERVICE_STOP_PENDING
// SERVICE_CONTINUE_PENDING
// SERVICE_PAUSE_PENDING
//
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
//
// sService
// service name, ie: Alerter

function ServiceGetStatus(sMachine, sService : string ) : DWord;
var
  schm, // service control manager handle
  schs : SC_Handle; // service handle
  ss : TServiceStatus; // service status
  dwStat : DWord; // current service status
begin
  dwStat := 0;
  // connect to the service control manager
  schm := OpenSCManager( PChar(sMachine), Nil, SC_MANAGER_CONNECT);
  // if successful...
  if(schm > 0)then begin
    // open a handle to the specified service
    schs := OpenService( schm, PChar(sService),
      SERVICE_QUERY_STATUS); // we want to query service status
    // if successful...
    if(schs > 0)then begin
      // retrieve the current status of the specified service
      if(QueryServiceStatus( schs, ss))then begin
        dwStat := ss.dwCurrentState;
      end;
      CloseServiceHandle(schs); // close service handle
    end;
    CloseServiceHandle(schm); // close service control manager handle
  end;
  Result := dwStat;
end;



// start service
// return TRUE if successful
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
// sService
// service name, ie: Alerter
function ServiceStart(sMachine, sService : string ) : boolean;
var
  schm, // service control manager handle
  schs : SC_Handle; // service handle
  ss : TServiceStatus; // service status
  psTemp : PChar; // temp char pointer
  dwChkP : DWord; // check point
begin
  ss.dwCurrentState := 0;
  // connect to the service control manager
  schm := OpenSCManager( PChar(sMachine), Nil, SC_MANAGER_CONNECT);
  // if successful...
  if(schm > 0)then begin
    // open a handle to the specified service
    schs := OpenService( schm, PChar(sService),
      SERVICE_START or // we want to start the service and
      SERVICE_QUERY_STATUS); // query service status
    // if successful...
    if(schs > 0)then begin
      psTemp := Nil;
      if(StartService( schs, 0, psTemp))then begin
        // check status
        if(QueryServiceStatus( schs, ss))then begin
          while(SERVICE_RUNNING <> ss.dwCurrentState)do begin
            // dwCheckPoint contains a value that the service
            // increments periodically to report its progress
            // during a lengthy operation.
            dwChkP := ss.dwCheckPoint; // save current value
            // wait a bit before checking status again
            // dwWaitHint is the estimated amount of time
            // the calling program should wait before calling
            // QueryServiceStatus() again

            // idle events should be handled here...
            Sleep(ss.dwWaitHint);
            if(not QueryServiceStatus( schs, ss))then begin
              break; // couldn't check status break from the loop
            end;
            if(ss.dwCheckPoint < dwChkP)then begin
              // QueryServiceStatus didn't increment
              // dwCheckPoint as it should have.
              // avoid an infinite loop by breaking
              break;
            end;
          end;
        end;
      end;
      CloseServiceHandle(schs); // close service handle
    end;
    // close service control manager handle
    CloseServiceHandle(schm);
  end;
  // return TRUE if the service status is running
  Result := SERVICE_RUNNING = ss.dwCurrentState;
end;

// stop service
//
// return TRUE if successful
//
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
//
// sService
// service name, ie: Alerter
//
function ServiceStop(sMachine, sService : string ) : boolean;
var
  schm, // service control manager handle
  schs : SC_Handle; // service handle
  ss : TServiceStatus; // service status
  dwChkP : DWord; // check point
begin
  // connect to the service control manager
  schm := OpenSCManager(PChar(sMachine), Nil, SC_MANAGER_CONNECT);
  // if successful...
  if(schm > 0)then begin
    // open a handle to the specified service
    schs := OpenService( schm, PChar(sService),
      SERVICE_STOP or // we want to stop the service and
      SERVICE_QUERY_STATUS);// query service status
    // if successful...
    if(schs > 0)then begin
      if(ControlService( schs, SERVICE_CONTROL_STOP, ss))then begin
        // check status
        if(QueryServiceStatus( schs, ss))then begin
          while(SERVICE_STOPPED <> ss.dwCurrentState)do begin
            // dwCheckPoint contains a value that the service
            // increments periodically to report its progress
            // during a lengthy operation.

            // save current value
            dwChkP := ss.dwCheckPoint;
            // wait a bit before checking status again
            // dwWaitHint is the estimated amount of time
            // the calling program should wait before calling
            // QueryServiceStatus() again
            // idle events should be handled here...
            Sleep(ss.dwWaitHint);
            if(not QueryServiceStatus( schs, ss))then begin
              break; // couldn't check status break from the loop
            end;
            if(ss.dwCheckPoint < dwChkP)then begin
              // QueryServiceStatus didn't increment
              // dwCheckPoint as it should have.
              // avoid an infinite loop by breaking
              break;
            end;
          end;
        end;
      end;
      CloseServiceHandle(schs); // close service handle
    end;
    CloseServiceHandle(schm); // close service control manager handle
  end;
  // return TRUE if the service status is stopped
  Result := SERVICE_STOPPED = ss.dwCurrentState;
end;

function ServiceRunning(sMachine, sService : string ) : boolean;
begin
  result := ServiceGetStatus(sMachine, sService) = SERVICE_RUNNING;
end;

// Get a list of services
// return TRUE if successful
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
// dwServiceType
// SERVICE_WIN32,
// SERVICE_DRIVER or
// SERVICE_TYPE_ALL
// dwServiceState
// SERVICE_ACTIVE,
// SERVICE_INACTIVE or
// SERVICE_STATE_ALL
// slServicesList
// TStrings variable to storage
function ServiceGetList(sMachine : string; dwServiceType, dwServiceState : DWord;
  slServicesList : TStrings ): boolean;
const
  // assume that the total number of services is less than 4096.
  // increase if necessary
  cnMaxServices = 4096;
type
  TSvcA = array[0..cnMaxServices] of TEnumServiceStatus;
  PSvcA = ^TSvcA;
var
  j : integer;
  schm : SC_Handle; // service control manager handle
  nBytesNeeded, // bytes needed for the next buffer, if any
  nServices, // number of services
  nResumeHandle : DWord; // pointer to the next unread service entry
  ssa : PSvcA; // service status array
begin
  Result := false;
  slServicesList.Clear;
  // connect to the service control manager
  schm := OpenSCManager(PChar(sMachine), Nil, SC_MANAGER_ALL_ACCESS);
  // if successful...
  if(schm > 0)then begin
    nResumeHandle := 0;
    New(ssa);
    EnumServicesStatus( schm, dwServiceType, dwServiceState, ssa^[0],
      SizeOf(ssa^), nBytesNeeded, nServices, nResumeHandle );
    // assume that our initial array was large enough to hold all
    // entries. add code to enumerate if necessary.
    for j := 0 to nServices-1 do begin
      slServicesList.Add( StrPas(ssa^[j].lpServiceName ) + '=' + StrPas(ssa^[j].lpDisplayName ) );
    end;
    Result := true;
    Dispose(ssa);
    CloseServiceHandle(schm); // close service control manager handle
  end;
end;


end.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.051 Beiträge
 
Delphi 12 Athens
 
#5

AW: Delphi und Serviceanwendungen, demo?

  Alt 5. Mai 2018, 16:37
Der Code über mir sieht auf den ersten Blick bezüglich Unicode nicht schlecht aus.
Gut, die Fehlerbehandlung lässt manchmal etwas zu Wünschen über, falls es einen nicht nur interessiert ob etwas nicht ging, sondern auch warum es nicht ging.


----

Nja, der Code selbst läuft mit Unicode und könnte sich wohl auch im ANSI heimisch fühlen, aber da einige Typen generisch deklariert sind, ist es erstmal etwas egal. (TArray<> und Co. könnte man aber notfalls rauswerfen).

Für Start/Stop muß der Entwickler selber für die nötigen Rechte sorgen. (noch)

Das Ganze ist eine Pascal-OOP-Kapselung, also also in einer Klasse verpackt, zuzüglich globale Klasse mit Grundfunktionen, alles mit String statt PChar, ENUMs statt Konstanten und Eyceptions statt Errorcodes.
Und ich hatte da ein bissl mit DocInsight/HelpInsight und Attributen für die Dokumentation rumgespielt. [edit]nee, fehlte noch, aber es sollte selbsterklärend sein und alle Konstanten wurden noch nicht übersetzt[/edit]
> siehe h5u.WinAPI.pas

Und in die Basis-Units besser nicht so genau reingucken. Musste mal schnell bissl was rauswerfen, damit es kompiliert.
Angehängte Dateien
Dateityp: 7z h5u.WinAPI.7z (17,1 KB, 14x aufgerufen)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 5. Mai 2018 um 17:34 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.086 Beiträge
 
Delphi 12 Athens
 
#6

AW: Delphi und Serviceanwendungen, demo?

  Alt 5. Mai 2018, 20:53
http://cc.embarcadero.com/Item/28354

Hatte auf der Basis mal was gemacht, wenn es das ist was du suchst.

Geändert von Rollo62 ( 6. Mai 2018 um 20:34 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.142 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Delphi und Serviceanwendungen, demo?

  Alt 6. Mai 2018, 11:55
... Das ist deutlich einfacher, zudem hatten wir mit der Out-Of-Process COM Variante schon Probleme auf manchen Systemen, vor allem mit Antivirenprogrammen.
Hmm... "Out-Of-Process" das war der Begriff der mir nicht eingefallen war... Probleme... Doof!

Der Trick mit dem sich doppelt selbst startenden Programmen um Admin-Rechte zu bekommen, funktioniert leider in diesem Fall nicht, trotzdem Danke!

Mavarik
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.051 Beiträge
 
Delphi 12 Athens
 
#8

AW: Delphi und Serviceanwendungen, demo?

  Alt 6. Mai 2018, 12:03
Out-Of-Process ... neuer Prozess mit höheren Rechten ... komplett abgetrennt.

In-Process, da stellt man die Rechte für einen Thread um (genauso kann man auch den "Desktop" für einen Thread ändern, um z.B. auf die UAC-Fenster zugreifen zu können), aber da haben dann die anderen Threads Zugriff auf den gemeinsamen Speicher/Programmcode. Auch Threads von Fremd-Code aus DLLs, die dir jemand wie Maustreiber, TeamViewer oder weniger Böswillige in deinen Process gehookt haben.


Wenn dein Programm aber nicht das Recht zum Ändern der Rechte besitzt, dann funktioniert das nicht.
(vor allem in Firmenumgebungen ist da oftmls sehr viel eingeschränkt)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 6. Mai 2018 um 12:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.142 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Delphi und Serviceanwendungen, demo?

  Alt 6. Mai 2018, 12:13
Wenn dein Programm aber nicht das Recht zum Ändern der Rechte besitzt, dann funktioniert das nicht.
(vor allem in Firmenumgebungen ist da oftmls sehr viel eingeschränkt)
Das ist nicht das Problem... Aber ich glaube Daniel hatte mal als UAC noch ganz frisch war ein Demo gezeigt um einen "eigenen" Thread mit Admin-Rechten zu starten... Das Problem ist, wenn ich zum Beispiel in einer Resource eine mini-exe mitliefere die das alles kann, schlagen die Virenscanner wieder an.

Vielleicht finde ich in den Tiefen meiner Delphi-Sourcen noch die richtige procedure...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.051 Beiträge
 
Delphi 12 Athens
 
#10

AW: Delphi und Serviceanwendungen, demo?

  Alt 6. Mai 2018, 12:17
Du kannst auch dein Programm nochmals mit Adminrechten starten und via Parameter nur die gewünschte Aktion ausführen.

Der Witz: EXE und DLL sind praktisch das Gleiche (abgesehn von der Startprozedur).
Ich hatte auch mal ein Programm, das sich selber oder von Fremden als DLL geladen werden konnte.
> Ein Programm kann nicht nur Einwas machen.

Windows kann sogar in einer EXE mehrere Services laufen lassen.
Nur die TService-Implementierung von Delphi kann das nicht.
Man kann nativ nichtmal die selbe EXE/Service mehrmals in einem System starten (Startparameter/Registrierung überschreiben und beim Start manuell drauf reagieren)
- eine EXE mehrmals mit unterschiedlichem Namen starten
- oder mehrere Services aus einer EXE in unterschiedlichen Prozessen starten
- oder mehrere Services innerhalb eines Prozesses starten
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 6. Mai 2018 um 12:24 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz