| Autor |
Nachricht |
DerCoder
Mitglied
Benutzerprofil
Anmeldungsdatum: 04.07.2009
Beiträge: 183
|
DerCoder Mitglied
19:20:50 02.04.2012 Titel: |
"explorer.exe" per CreateProcess öffnet Arbeitsplatz |
Zitieren |
Hallihallo,
ich erstelle mir mit CreateDesktop einen zweiten, virtuellen Desktop und möchte gerne auf diesem gerne die Taskbar und die Desktopsymbole anzeigen lassen.
Dazu muss ich auf dem neuen Desktop lediglich per CreateProcess die "explorer.exe" starten und in der STARTUPINFO den lpDesktop festlegen - so viel weiß ich schon
Soweit klappt das auch wunderbar! Das Ding ist nur, dass auf dem neuen Desktop zwar Taskbar und Desktopsymbole angezeigt werden, aber es wird auch der Arbeitsplatz geöffnet, beziehungsweise das Fenster Bibliotheken.
Wie kann ich das unterbinden/verhindern?
Falls ihr Codesnippets braucht oder Fragen habt, gebt mir bitte Bescheid
Danke im Voraus, DerCoder |
|
|
|
 |
desktops
Unregistrierter
|
desktops Unregistrierter
08:56:52 03.04.2012 Titel: |
|
Zitieren |
Poste mal deinen Code. Ich habe mal genau dasselbe ausprobiert und es hat funktioniert, dass der neue Desktop dann eine Taskleiste hatte. Vielleicht hast du irgendetwas anders gemacht. |
|
|
|
 |
Martin Richter
Moderator
Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 14172
|
Martin Richter Moderator
10:55:51 03.04.2012 Titel: |
|
Zitieren |
Normalerweise legt man den Primären Desktop fest auf dem dann auch der Taskbar erscheint.
Zudem, wie bitte schaftst Du es, dass ein neuer Explorer mit Taskbar erzeugt wird, wenn ein Prozessbereits besteht?
Den Taskbar kann man nicht zweimal starten... oder schießt Du den ab?
Das wäre natürlich ein ganz mieses Ding. |
_________________ Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
|
|
 |
desktops
Unregistrierter
|
desktops Unregistrierter
11:38:58 03.04.2012 Titel: |
|
Zitieren |
Jeder Desktop kann einen eigenen explorer.exe Prozess mit eigener Taskleiste haben. Auf diese Weise funktioniert auch "Desktops" von Sysinternals. |
|
|
|
 |
Martin Richter
Moderator
Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 14172
|
Martin Richter Moderator
12:32:32 03.04.2012 Titel: |
|
Zitieren |
| desktops schrieb: | | Jeder Desktop kann einen eigenen explorer.exe Prozess mit eigener Taskleiste haben. Auf diese Weise funktioniert auch "Desktops" von Sysinternals. |
Upps. Ich habe das mit Monitoren verwechselt... Monitor!=Desktop...
Sorry! |
_________________ Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
|
|
 |
DerCoder
Mitglied
Benutzerprofil
Anmeldungsdatum: 04.07.2009
Beiträge: 183
|
DerCoder Mitglied
01:55:15 04.04.2012 Titel: |
|
Zitieren |
| desktops schrieb: | | Poste mal deinen Code. Ich habe mal genau dasselbe ausprobiert und es hat funktioniert, dass der neue Desktop dann eine Taskleiste hatte. Vielleicht hast du irgendetwas anders gemacht. |
| C++: | 1 2 3 4 5 6 7 8 | ZeroMemory(&_explorerSI, sizeof(_explorerSI));
ZeroMemory(&_explorerPI, sizeof(_explorerPI));
_explorerSI.cb = sizeof(_explorerSI);
_explorerSI.lpTitle = _deskName;
_explorerSI.lpDesktop = _deskName;
// _explorerSI.wShowWindow = SW_HIDE; // ÄNDERT LEIDER NICHTS!
_deskHandle = CreateDesktop(_deskName, NULL, NULL, 0, GENERIC_ALL, NULL);
CreateProcess(NULL, _explorerPath, NULL, NULL, false, 0, NULL, NULL, &_explorerSI, &_explorerPI); | |
Das ist in der Funktion prepare() Funktion meiner Klasse VirtualDesk. Die Membervariablen werden per Konstruktor gesetzt. Mit prepare() wird der neue, virtuelle Desktop nur noch vorbereitet für den Gebrauch.
Kannst du mal deine Funktion posten, dann kann ich die mit meiner Klasse abgleichen
Bei mir klappt auch alles! Der Desktop wird erstellt, mit SwitchDesktop(HDESK) und SetThreadDesktop(HDESK) wird auch tatsächlich zum Desktop gewechselt.
!NUR! dieses blöde Arbeitsplatz/Bibliotheken Fenster nervt!
Wie ich eben festgestellt habe, öffnet sich das besagte Fenster nur, wenn ich das Programm mehrmals starte.
Meine Theorie ist, dass der Prozess, den ich erstelle, nachdem der Desktop geschlossen wurde, immernoch existiert. Aber auch wenn ich ihn mit TerminateProcess(HANDLE, UINT) beende, ändert sich nichts an meinem Endproblem. Habe ich keine Rechte, um die explorer.exe zu beenden?
Danke fürs Lesen und eine ruhige und schöne Nacht noch :P
DerCoder |
Zuletzt bearbeitet von DerCoder am 01:56:44 04.04.2012, insgesamt 2-mal bearbeitet |
|
 |
desktops
Unregistrierter
|
desktops Unregistrierter
09:38:42 04.04.2012 Titel: |
|
Zitieren |
Auf jeden Fall gilt, dass ein Desktop solange existiert, bis alle Prozesse auf diesem Desktop beendet wurden und alle Handles zu dem Desktop geschlossen wurden. Das solltest du auf jeden Fall bedenken, wenn du weiter an deinem Programm arbeitest.
Dein Problem mit TerminateProcess resultiert wahrscheinlich daraus, dass TerminateProcess nur das Beenden des Prozesses einleitet, nicht aber darauf wartet, bis der Prozess beendet wurde. Du solltest also nach dem TerminateProcess noch mit WaitForSingleObject auf das Ende des Prozesses warten.
Hast daran gedacht, am Ende alle Handles der PROCESS_INFORMATION Struktur zu schließen? |
|
|
|
 |
DerCoder
Mitglied
Benutzerprofil
Anmeldungsdatum: 04.07.2009
Beiträge: 183
|
DerCoder Mitglied
11:47:41 04.04.2012 Titel: |
|
Zitieren |
Okay, das klingt logisch.
Wenn der Desktop wieder gelöscht werden soll, muss die destroy() Funktion aufgerufen werden, die wie folgt aussieht:
| C++: | TerminateProcess(_explorerPI.hProcess, 0);
WaitForSingleObject(_explorerPI.hProcess, 3000); // Soll ich INFINITE nehmen?
CloseDesktop(_deskHandle);
CloseHandle(_deskHandle);
CloseHandle(_explorerPI.hProcess);
CloseHandle(_explorerPI.hThread); | |
Gibt es eigentlich eine Funktion, mit der ich alle Prozesse, die auf einem Desktop laufen, enumerieren kann? Was ich nämlich damit erreichen möchte, ist, dass wenn der Desktop mit destroy() oder dem Destruktor gelöscht wird, die laufenden Prozesse "gesichert" werden und auf den Hauptdesktop verschoben werden.
Achja, was mir grad auch noch einfällt: Wenn mein Programm beendet wird und bereits auf einen anderen Desktop gewechselt wurde (also der aktuelle Desktop ist nicht der Hauptdesktop!!!), wie komme ich dann an das Handle des Hauptdesktops bzw. kann ich überhaupt noch auf den Hauptbildschirm wechseln?
Das sind wieder ne Menge Fragen, aber ich habe leider im Internet keine Antworten darauf gefunden.
Danke und liebe Grüße, DerCoder |
|
|
|
 |
desktops
Unregistrierter
|
desktops Unregistrierter
14:05:18 04.04.2012 Titel: |
|
Zitieren |
Also ich würde schon einen Timeout für WaitForSingleObject nehmen, vielleicht 5000 Millisekunden. Aber das musst du selbst entscheiden.
Den Handle des Hauptdesktops bekommst du, indem du den Desktop mit dem Namen "Default" mit OpenDesktop öffnest. Alternativ kannst du den Desktop, auf dem dein Prozess gestartet wurde, mit GetThreadDesktop abfragen.
Die Prozesse auf einem bestimmten Desktop abzufragen scheint ziemlich schwierig zu sein. Du musst alle Prozesse durchlaufen (mit CreateToolhelp32Snapshot, Process32First und Process32Next) und bei jedem Prozess prüfen, ob der Prozess zu deinem Desktop gehört. Dann musst du die Threads durchlaufen (CreateToolhelp32Snapshot, Thread32First, Thread32Next). Du kannst dann mit GetThreadDesktop einen Handle zu dem Desktop eines Threads bekommen. Mit diesem Handle kannst du den Namen des Desktops bekommen, indem du GetUserObjectInformation mit nIndex auf UOI_NAME gesetzt aufrufst. Diesen Namen musst du dann case insensitive mit Namen deines Desktops vergleichen.
Soweit ich weiß, ist es nicht möglich, den Desktop, auf dem ein fremder Prozess läuft zu ändern. SetThreadDesktop funktioniert ja auch nur mit eigenen Threads. Und wenn ein Fenster auf einem bestimmten Desktop erstellt wurde, kann es dann auch nicht plötzlich auf einen anderen Desktop verschoben werden. |
|
|
|
 |
DerCoder
Mitglied
Benutzerprofil
Anmeldungsdatum: 04.07.2009
Beiträge: 183
|
DerCoder Mitglied
18:25:09 04.04.2012 Titel: |
|
Zitieren |
Tausend Dank für deine ausführlichen Erläuterungen!
Ich habe ein Timeout von 5000ms probiert und auch INFINITE... nichts.
Der von mir erstellte Prozess wird partout nicht beendet. Mir fallen absolut keine weiteren Ideen ein.
Kann ich eigentlich alle offenen Desktops abfragen? |
|
|
|
 |
|
Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
|
|
|
|
|