Bonjour,
Commençons par situer le contexte...
J'ai écrit un petit programme de capture d'écran (que j'appellerai "sc.exe").
Il est possible de le lancer en spécifiant un délai d'attente avant que la capture ne soit faite. Donc, si je lance "sc.exe -d 5000", le programme attend 5 secondes puis fait la capture.
Pour capturer le contenu de l'écran, je commence par récupérer un handle sur la fenêtre correspondant au bureau (GetDesktopWindow()) puis je procède de façon classique (GetDC()+CreateCompatibleDC()+CreateCompatibleBitmap()...etc...).
Problème...
Si je lance "sc.exe -d 5000" puis appuie aussitôt sur Ctrl+Alt+Suppr et attends 10 secondes avant de cliquer sur "Annuler", je passe du bureau "WinSta0\Default" au bureau "WinSta0\Winlogon" et après retour à "WinSta0\Default" je constate que ma capture est "vide" (image noire), et ce même si mon programme est lancé en tant qu'utilisateur "SYSTEM".
Recherche de solution...
J'ai modifié mon programme pour en produire deux autres : "scEnum.exe" et "scInput.exe".
"scEnum.exe"
Le but de "scEnum.exe" était de vérifier que je pouvais capturer le contenu du bureau "Winlogon" (et savoir si c'était bien lui qui était visible). Son principe est le suivant : utilisation EnumWindowStations(), appel (dans le callback) à SetProcessWindowStation() pour rattacher le processus à la station énumérée puis utilisation de EnumDesktops(), appel de SetThreadDesktop() (dans le callback de EnumDesktop() bien sûr) pour rattacher le thread au desktop voulu et, enfin, capture du contenu du desktop courant via la méthode utilisée dans précédemment (dans "sc.exe").
Si "scEnum.exe" est lancé avec les droits "SYSTEM", j'obtiens N captures et l'une d'elle contient bien le bureau "Winlogon" si il est visible au moment de la capture.
Mais : j'ai N captures (dont N-1 vides) alors que je n'en veux qu'une.
"scInput.exe"
Le but de "scInput.exe" était de vérifier si OpenInputDesktop() me permettrait de trouver *LE* bureau actuellement visible.
En effet, lorsqu'il est visible, je peux interagir avec lui (cliquer sur "Verrouiller", "Annuler") et MSDN nous dit :
Mais c'est apparemment faux (ou alors je n'ai pas la même définition de "user input") puisque "scInput.exe" ne capture qu'une image "vide" (en tant que "SYSTEM" : en tant qu'administrateur OpenInputDesktop() échoue et getLastError() renvoie 2).Envoyé par MSDN
Autrement dit, OpenInputDesktop() semble toujours renvoyer le HDESK de "WinSta0\Default" même si le bureau avec lequel j'interagis est "WinSta0\Winlogon".
Question
Comment savoir (de façon certaine) quel est le bureau actuellement visible (éventuellement pour une WindowStation donnée) ?
Merci d'avance pour votre aide (et votre compréhension si je me suis mal exprimé : c'est mon premier "post").
Notes :
1) j'ai essayé, dans "scEnum.exe", de vérifier les valeurs renvoyées par IsWindowVisible() et IsWindowEnabled() (en leur passant le HWND du desktop courant), mais plusieurs bureaux (enfin : leur fenêtre) sont visibles et activés en même temps.
2) pour régler le problème des permissions (obligation de lancer le programme en tant que "SYSTEM"), je pensais créer un service qui se chargerait de la capture, le programme ne servant plus qu'à démarrer/arrêter/communiquer avec ce service. Voyez-vous d'autres options (propres) ?
Partager