Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Mit Service auf Desktop zeichnen (https://www.delphipraxis.net/76522-mit-service-auf-desktop-zeichnen.html)

gsh 5. Sep 2006 20:14


Mit Service auf Desktop zeichnen
 
Hi DPler

Ich stehe vor einem großen Problem. Ich hab einen Service geschrieben und mit dem möchte jetzt eine andere Exe starten, damit ich etwas auf den Desktop zeichnen kann, weil das aus dem Service heraus (wenn interactive = false) imho nicht geht. Deshalb hab ich mir gedacht, ich mache dafür eine eigene Exe die des für mich erledigt. Da der Service aber unter dem SYSTEM Account ausgeführt wird (was er auch soll), dann wird die mit shellexcute aufgerufene exe auch als SYSTEM ausgeführt und somit sieht man nichts davon. An des RunAs hab ich auch schon gedacht, aber da weiß ich nicht das Benutzer Passwort dafür.

Ich hab mir drei mögliche Wege überlegt. Welcher ist der beste und wie kann ich ihn erreichen?

1. Service kann doch auf den Desktop zugreifen und etwas auf den desktop zeichen, ohne Interactive und somit auch ohne die andere Exe.
2. Ich kann die exe anderes öffnen des sie zwar unter dem aktuell eingelogten user ausgeführt wird, aber ohne des Passwort von ihm zu haben.
3. Die Exe dazu bringen auch vom SYSTEM konto aus auf den Desktop was zeichen


Für weitere Vörschläge oder Lösungswege bin ich natürlich offen :zwinker:

Luckie 5. Sep 2006 20:38

Re: Mit Service auf Desktop zeichnen
 
Ruf in der Exe mal MSDN-Library durchsuchenSwitchDesktop auf, eventuell geht das damit.

gsh 5. Sep 2006 23:43

Re: Mit Service auf Desktop zeichnen
 
k des wäre möglichkeit nummer drei
ich hab mir des jetzt mal in der in der MSDN angeschaut und auch versucht einzubauen nur brauch des da: "HDESK hDesktop"
dieses müsste ich zwar mit OpenDesktop bekommen aber da überfordern mich die parameter total

außerdem kann es sein das ich dann einen ganz anderen desktop sehe und wenn ich des programm beende und des nicht mehr zurückstelle ich nicht mehr zum alten zurück komme?


irgendwie wär mir die 1 Lösung lieber ... naja wenn es nicht geht dann gehts nicht aber wenn es geht dann bin ich für die erste :mrgreen:

Vjay 6. Sep 2006 00:15

Re: Mit Service auf Desktop zeichnen
 
Soweit ich weiss muss der User selber die Exe starten (Autostart), bzw. du tust es für ihn mit seinem Passwort.

Gibbet übrigens nen lustigen Artikel zu: http://blogs.msdn.com/oldnewthing/ar...22/712677.aspx

SirThornberry 6. Sep 2006 06:12

Re: Mit Service auf Desktop zeichnen
 
Eventuell genügt es ja schon bei CreateProcess den Desktop anzugeben auf dem dein Zweitprogramm laufen soll

gsh 6. Sep 2006 10:08

Re: Mit Service auf Desktop zeichnen
 
Zitat:

Zitat von Vjay
Soweit ich weiss muss der User selber die Exe starten (Autostart), bzw. du tust es für ihn mit seinem Passwort.

An des hab ich auch schon gedacht aber des fällt flach da die exe nur unter bestimmten umständenn gestarten werden soll, und mit seinem passwort hab ich gesagt geht nicht da ich nicht sein passwort kenne. Oder schaut des gut aus?: Beim Setup "Please enter your Admin Password"

Zitat:

Zitat von SirThornberry
Eventuell genügt es ja schon bei CreateProcess den Desktop anzugeben auf dem dein Zweitprogramm laufen soll

Hmm aber da hab ich wieder des Problem wie vorne beschrieben:
Zitat:

Zitat von ich
außerdem kann es sein das ich dann einen ganz anderen desktop sehe und wenn ich des programm beende und des nicht mehr zurückstelle ich nicht mehr zum alten zurück komme?


gsh 7. Sep 2006 16:16

Re: Mit Service auf Desktop zeichnen
 
*push*

Luckie 7. Sep 2006 17:23

Re: Mit Service auf Desktop zeichnen
 
Bist du mal dem Link von Vjay gefolgt? Es gibt nicht DEN Desktop. Seit es unter Windows XP das FastUserSwitching gibt, können mehrere Benutzer einen interaktiven Desktop haben. Auf welchen willst du denn dann zeichnen? Auf alle? Auf einen bestimmten?

gsh 7. Sep 2006 20:27

Re: Mit Service auf Desktop zeichnen
 
Also da diese Computer in der Domäne hängen gibt es imho nur einen. Aber im zweifelsfall auf alle oder auf den aktiven dews ist in meinem fall egal :zwinker:

gsh 9. Sep 2006 13:03

Re: Mit Service auf Desktop zeichnen
 
*push*

Olli 10. Sep 2006 09:55

Re: Mit Service auf Desktop zeichnen
 
Habe keinen Bock o.g. zu wiederholen. Fakt ist, daß ein Service mal erstens nie interaktiv sein sollte (Stichwort: Bei Google suchenShatter-Attack), was schon einige AV-Hersteller erfahren durften.

Du kannst einem Service-Thread auch sagen, daß er sich an einen anderen Desktop hängen soll, der aber immernoch in der gleichen Window-Station sein muß (MSDN-Library durchsuchenSetThreadDesktop). Zuvor müßte dein Prozeß aber Zugriff auf die WindowStation und den Desktop bekommen und dann die WindowStation wechseln (MSDN-Library durchsuchenSetProcessWindowStation). Aus dem Betrachten der Objektverzeichnis-Hierarchie nehme ich an, daß man die WindowStations einem jeweiligen Terminal zuordnen kann (wie andere Objekte auch). Allerdings ist das offenbar im PSDK nicht dokumentiert und ich habe keine Zeit mich ausführlich damit zu beschäftigen. Es gibt da spezielle DLLs zum Thema (WinSta.dll usw). Allesamt mit undokumentierten Funktionen die in MS-Tools (z.B. TaskManager) rege Verwendung finden.

Ich an deiner Stelle würde mir eine Ersatz-GINA basteln. Diese GINA kann jederzeit alles auf allen interaktiven Desktops (auch den SAS-Desktops) machen, wenn du es brauchst. Etwas Code (veraltet, weil Delphi) hier: http://assarbad.info/stuff/!export/ancient/agreementgina.rar

Zwar erfordert das unter Vista eine Neuausrichtung (dort gibt es eine neue Methode welche die GINA ersetzt, soweit ich weiß), aber für alle vorigen NT-Systeme bist du voll kompatibel.

SirThornberry 10. Sep 2006 12:06

Re: Mit Service auf Desktop zeichnen
 
Ich hab mich auch mal damit beschäftigt und komm jetzt an folgender Stelle nicht weiter:
Stand:
- Mein Service läuft jetzt in der Station "WinSta0" (also nicht mit in der Station "Service-0x0-3e7$")
- Somit kann ich auch den Hauptdesktop "Default" (und natürlich auch alle anderen Desktops in "WinSta0") öffnen
- Ich kann auch einen Process auf dem Desktop starten (ich geh zumindest davon aus das der Prozess auf dem Desktop gestartet wurde da ich in der eintsprechenden WinStation bin und bei CreateProcess den Desktop "Default" angegeben hab. Der Prozess tauch auch im Taskmananger auf, allerdings seh ich das Programm optisch nicht.

Muss ich da noch irgendwas beachten damit das Programm sichtbar ist auf dem Desktop?


PS.:
Auf den Desktop zeischnen und Formulare anzeigen (auch auf Winlogon) kann ich übrigens. Es scheitert wirklich nur noch am starten eines Prozesses auf dem Desktop.

Olli 10. Sep 2006 12:35

Re: Mit Service auf Desktop zeichnen
 
Das kann man ohne Code natürlich kaum sagen, denn deine Frage ist schon sehr spezifisch.

Ich nehme an, daß entweder die ACLs des Desktops in deinem Fall noch nicht stimmen, du bei CreateProcess was falsch machst, oder der Thread zuvor ein Impersonate machen muß um was auf dem Desktop zu starten. Wie gesagt, nix genaues weiß man nich - zumindest ohne deinen exakten Code.

SirThornberry 10. Sep 2006 15:20

Re: Mit Service auf Desktop zeichnen
 
So wechsle ich den Desktop (so das Zeischnen über GetDC(0) funktioniert und erzeugte TForms auch auf diesem Desktop landen)
Delphi-Quellcode:
var
  lDesktop,
  lStationNew  : Cardinal;
begin
  lStationNew := OpenWindowStation('WinSta0', True, GENERIC_ALL);
  if (lStationNew <> 0) then
  begin
    SetProcessWindowStation(lStationNew);
    lDesktop := OpenDesktop('Default', DF_ALLOWOTHERACCOUNTHOOK, True, GENERIC_ALL);
    if (lDesktop <> 0) then
    begin
      if SetThreadDesktop(lDesktop) then
        fCouldSwitch := True;
      CloseDesktop(lDesktop);
    end;
    CloseWindowStation(lStationNew);
  end;

Olli 10. Sep 2006 15:40

Re: Mit Service auf Desktop zeichnen
 
Hast du mal versucht die Zeile "fCouldSwitch := True;" durch dein CreateProcess (Desktop und WinSta nicht explizit angeben!) zu ersetzen?

SirThornberry 10. Sep 2006 15:57

Re: Mit Service auf Desktop zeichnen
 
Ok, damit gehts. Mit dem unschönen Nebeneffekt das sich zum Beispiel Notepad nicht zeichnet. So als würden keine Messages ankommen. Und aus irgend einem Grund kann ich in meiner Anwendung zwar klicken aber nix schreiben. (wenn ich mein Form bzw. Notepad auf dem Desktop "winlogon" ausführe)

Olli 10. Sep 2006 16:53

Re: Mit Service auf Desktop zeichnen
 
Zitat:

Zitat von SirThornberry
Ok, damit gehts. Mit dem unschönen Nebeneffekt das sich zum Beispiel Notepad nicht zeichnet. So als würden keine Messages ankommen. Und aus irgend einem Grund kann ich in meiner Anwendung zwar klicken aber nix schreiben. (wenn ich mein Form bzw. Notepad auf dem Desktop "winlogon" ausführe)

Erbt der erzeugte Prozess die Handles? Machst du es so wie in deinem obigen Beispiel, wird also das Handle (Desktop, WinSta) sofort wieder geschlossen?

SirThornberry 10. Sep 2006 17:09

Re: Mit Service auf Desktop zeichnen
 
Ob ich die Handles Sofort wieder schließe oder nicht ändert nichts am verhalten (grad probiert). Die Handles hab ich bisher nicht vererbt, "bInheritHandles" war also False. Wenn ich es auf "True" setze hab ich den Effekt das ich die Anwendung gar nicht zu gesicht bekomme (die bleibt dann unsichtbar)

Olli 10. Sep 2006 20:47

Re: Mit Service auf Desktop zeichnen
 
Zitat:

Zitat von SirThornberry
Ob ich die Handles Sofort wieder schließe oder nicht ändert nichts am verhalten (grad probiert). Die Handles hab ich bisher nicht vererbt, "bInheritHandles" war also False. Wenn ich es auf "True" setze hab ich den Effekt das ich die Anwendung gar nicht zu gesicht bekomme (die bleibt dann unsichtbar)

Faszinierend. Kannst du mir bitte mal dein Programm in einem kompilierbaren Zustand mit kurzer Erläuterung der einzelnen Dateien zuschicken?! Würde es gern mal selbst versuchen.

gsh 11. Sep 2006 11:35

Re: Mit Service auf Desktop zeichnen
 
@SirThornberry: Hi kannst du mir verraten wie du es geschaft hast das das Formular angezeigt wird? Denn ich hab des so probiert, aber es wird trozdem nicht angezeigt:
Delphi-Quellcode:
var
  lDesktop, lStationNew  : Cardinal;
begin
  lStationNew := OpenWindowStation('WinSta0', True, GENERIC_ALL);
  if (lStationNew <> 0) then
  begin
    SetProcessWindowStation(lStationNew);
    lDesktop := OpenDesktop('Default', DF_ALLOWOTHERACCOUNTHOOK, True, GENERIC_ALL);
    if (lDesktop <> 0) then
    begin
      if SetThreadDesktop(lDesktop) then
      begin
        Form1 := TForm1.Create(Service1);
        Form1.Show;
      end;
      CloseDesktop(lDesktop);
    end;
    CloseWindowStation(lStationNew);
  end;
end;

SirThornberry 11. Sep 2006 11:39

Re: Mit Service auf Desktop zeichnen
 
Es ist entscheident an welcher Stelle du den Source plazierst. SetThreadDesktop funktioniert nur wenn der Thread noch keine Handles zum aktuellen Desktop offen hat. Am besten du baust in den Source einige Debugausgaben ein (zum Beispiel schreiben in Datei etc.) um zu sehen an welcher Anweisung es hakt.
Wenn du den aufruf von unten in einen Frischen Thread packst sollte es zum Beispiel klappen weil der Thread noch keine Handles auf einen Desktop offen hat.

Olli 11. Sep 2006 11:53

Re: Mit Service auf Desktop zeichnen
 
Keinen Bock es zu schicken oder ist es was von deiner Firma?

SirThornberry 11. Sep 2006 12:01

Re: Mit Service auf Desktop zeichnen
 
Doch, ich werds noch schicken. Das Problem ist das ich das Projekt jetzt in eine andere Richtug weiter gebaut hab. Ich hab also den Button zum starten von Prozessen raus genommen weil es nicht funktioniert hat und bin dann zu diesem Ergebnis gekommen:
http://www.delphipraxis.net/internal...=608398#608398

Ich könnte im Moment nur dieses Projekt schicken ohne den Button. Aber ich wollt bis heute Abend warten wenn ich bischen mehr zeit hab und das Projekt kopieren und einen Button einbauen.

gsh 12. Sep 2006 11:24

Re: Mit Service auf Desktop zeichnen
 
ok ich glaub ich weiss jetzt mein Problem
Delphi-Quellcode:
var
  lDesktop, lStationNew  : Cardinal;
begin
  lStationNew := OpenWindowStation('WinSta0', True, GENERIC_ALL);
  if (lStationNew <> 0) then
  begin
    SetProcessWindowStation(lStationNew);
    lDesktop := OpenDesktop('Default', DF_ALLOWOTHERACCOUNTHOOK, True, GENERIC_ALL);
    if (lDesktop <> 0) then
    begin
      if SetThreadDesktop(lDesktop) then //Hier wird immer false zurück gegeben und somit des Form1 nicht erzeugt
      begin
        Form1 := TForm1.Create(Service1);
        Form1.Show;
      end;
      CloseDesktop(lDesktop);
    end;
    CloseWindowStation(lStationNew);
  end;
end;
aber warum? Ich hab des jetzt testweiße im ServiceCreate aufgerufen, also als allererstes. :wall:

gsh 13. Sep 2006 07:37

Re: Mit Service auf Desktop zeichnen
 
*push*

SirThornberry 13. Sep 2006 08:26

Re: Mit Service auf Desktop zeichnen
 
Hast du denn, wie ich es geschrieben hab, das ganze in einen Thread ausgelagert? Das Create dürfte der falsche ort sein denn du kannst die Exe auch mit doppelklick öffnen um Dinge anzuzeigen etc. Zu dem Zeitpunkt sind also mit hoher Wahrscheinlichkeit Handles offen.

gsh 13. Sep 2006 10:50

Re: Mit Service auf Desktop zeichnen
 
Zitat:

Zitat von SirThornberry
Hast du denn, wie ich es geschrieben hab, das ganze in einen Thread ausgelagert? Das Create dürfte der falsche ort sein denn du kannst die Exe auch mit doppelklick öffnen um Dinge anzuzeigen etc. Zu dem Zeitpunkt sind also mit hoher Wahrscheinlichkeit Handles offen.

Des mit dem in einem Thread auslageren muss ich überlesen haben. Naja k ich habs jetzt jedenfalls in einem thread ausgelagert und nun funktioniert SetThreadDesktop schon mal.

Nur die Form wird immer noch nicht angezeigt.
Das Problem ist glaub ich des er irgendwie nach dem show abstirbt:
Delphi-Quellcode:
if SetThreadDesktop(lDesktop) then
begin
  Log('Erzeuge Form');//Wird ausgeführt
  Form1 := TForm1.Create(nil);//Wird ausgeführt
  Form1.Show;//Wird ausgeführt
  Log('Form wurde erzeugt');//Wird NICHT ausgeführt
end;
Aber warum solltet beim create schon handels offen sein?

SirThornberry 13. Sep 2006 10:56

Re: Mit Service auf Desktop zeichnen
 
weil das bei dem serviceobject wohl so ist. Das dein Form nicht angezeigt wird liegt dann daran das du in dem Thread keine Nachrichtenschleife hast. Im Haupttrhead wird diese durch Application.Run angeschuppst. Aber das ist ein anderes Thema und hat nichts mit dem Zeischnen auf den Desktop von einem Service aus zu tun (denn anstelle das Form anzuzeigen kannst du ja auf dem Desktop zeischnen).

gsh 13. Sep 2006 11:02

Re: Mit Service auf Desktop zeichnen
 
ne eine Nachrichten scheife hab ich nicht ... und wie mach ich die?

SirThornberry 13. Sep 2006 11:13

Re: Mit Service auf Desktop zeichnen
 
Wie du die machst findest du über die Suche (NonVCL). Allerdings ist die VCL nicht Threadsicher und arbeitet auch in Threads nicht ordentlich/Fehlerfrei.

gsh 13. Sep 2006 13:35

Re: Mit Service auf Desktop zeichnen
 
darf man fragen wie du des gemacht hast?

SirThornberry 13. Sep 2006 14:51

Re: Mit Service auf Desktop zeichnen
 
Zitat:

Zitat von gsh
darf man fragen wie du des gemacht hast?

Ist geheim :mrgreen: Ich hab kein Interesse daran das jeder einen Service schreibt welcher dann Unsinn auf dem Desktop macht. Es ist schon heikel genug das der Source hier zu finden ist wie man von einem Service aus auf den User-Desktop gelangt.

gsh 13. Sep 2006 15:36

Re: Mit Service auf Desktop zeichnen
 
ach nun sei doch nicht so :zwinker:

Du könntest es mir ja als pn oder email schicken, ich bin 18 und werde gewissenhaft mit dem code umgehen und ihn nicht weitergeben.

Bitte :duck:


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:09 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