2010-11-23 3 views
3

Visual C++ 2008OpenInputDesktop() pour déterminer Secure/Connexion Bureau

Comment établir si oui ou non l'utilisateur actuellement interactif est soit au bureau verrouillé (L Windows Key) ou l'écran d'arrêt (Vista ou 7) attendre la fermeture des programmes lors de la déconnexion.

HDESK hd = OpenInputDesktop (0, faux, READ_CONTROL); Cela fonctionne très bien pour une application utilisateur sur le bureau par défaut, mais échoue avec le code d'erreur 5 sur les postes de travail verrouillés ou arrêtés, car l'utilisateur n'a pas les autorisations nécessaires pour ouvrir l'objet Bureau sécurisé. L'appel à partir d'un service s'exécutant sous le compte système renvoie l'erreur 1 (fonction non valide).

Je crois que le Service est dans tous les cas dans la mauvaise session (Session 0) et est incapable de déterminer le bureau interactif pour toute autre session.

J'ai une application fonctionnant sous l'utilisateur actuellement interactif, et aussi, le service de système fonctionnant, ainsi pourrait faire le code de l'un ou l'autre.

Est-ce que je devrais peut-être essayer d'énumérer toutes les sessions, stations de fenêtre et bureaux?

Même alors, comment puis-je déterminer le bureau actuellement interactif si je peux seulement faire l'appel à OpenInputDesktop à partir du service système dans la session 0?

+0

Peut-être la réponse serait de surveiller en quelque sorte lorsque l'utilisateur bascule ordinateurs de bureau? Est-ce possible? – Peter350

Répondre

3

Je pense que vous pouvez essayer ces méthodes:

  • d'un processus en cours d'exécution dans l'utilisateur actuellement interactif:
    Utilisez WTSRegisterSessionNotification pour vous inscrire pour les notifications de changement de session. Une fois enregistré, le processus interactif recevra des notifications de connexion/déconnexion. Plus d'informations peuvent être trouvées ici:
    http://msdn.microsoft.com/en-us/library/aa383841.aspx
    http://blogs.msdn.com/b/oldnewthing/archive/2006/01/ 04/509194.aspx

  • d'un service (en cours d'exécution en session 0):
    • Utilisez GetProcessWindowStation pour obtenir la poignée de la station actuelle du service et de l'enregistrer pour une utilisation ultérieure.
    • Utilisez WTSGetActiveConsoleSessionId pour obtenir l'ID de session de la session interactive en cours.
    • Obtenir le nom de la station correspondant à l'ID de la session en cours en utilisant WTSQuerySessionInformation avec la classe d'informations WTSWinStationName.
    • Ouvrir cette station en utilisant OpenWindowStation. Définissez cette station sur votre processus de service en utilisant SetProcessWindowStation. Maintenant, vous pouvez utiliser OpenInputDesktop pour vérifier si l'utilisateur s'est connecté ou non.
    • Fermez la fenêtre interactive ouverte en appelant le CloseWindowStation. Réinitialisez la station de service de la fenêtre d'origine en appelant le SetProcessWindowStation avec la poignée de la station enregistrée précédemment.

PS: À l'heure actuelle, "WinSta0" est la seule borne interactive dans Windows.Ainsi, vous pouvez ignorer les appels WTSGetActiveConsoleSessionId et WTSQuerySessionInformation.

+0

Je ne pense pas que la deuxième méthode fonctionne correctement. Un service exécuté dans la session 0 échouera SetProcessWindowStation() pour définir winsta0 dans session1 à moi-même. Parce que la station de fenêtre sur SetProcessWindowStation() doit être associée à la session en cours. – sMiLo

1

Attention: MSDN à propos WTSQuerySessionInformation avec WTSWinStationName:

Note: Malgré son nom, en précisant ce type ne retourne pas le nom de la station de fenêtre. Au lieu de cela, il renvoie le nom de la session Remote Desktop Services. Chaque session Remote Desktop Services est associée à une station de fenêtre interactive. Actuellement, étant donné que le seul nom de station de fenêtre pris en charge pour une station de fenêtre interactive est "WinSta0", chaque session est associée à sa propre station de fenêtre "WinSta0". Pour plus d'informations, reportez-vous à la section Stations Windows.