winapi - Hvad sker der bag 'Windows låseskærmen'?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har arbejdet med windows automatisering og overvågning.


Hvad sker der nøjagtigt, når jeg låser skærmen på en Windows-maskine?


Jeg arbejder i øjeblikket med Windows 7, er der store forskelle på opførelsen, hvis jeg skifter til Vista eller serverversionerne?
Er der stadig et skrivebord, der kan fås via api? S?
Jeg ved, at jeg stadig kan sende nøgleslag og museklik til bestemte vinduer (via ControlSend og ControlClick), men der synes ikke at være noget 'desktop' i sig selv. [1] [2]


Kan nogen kaste lys over hele denne ting eller pege på en læsbar kilde, hvor jeg kunne få et overblik over emnet?

Bedste reference


Hvad der sker er, at Windows skifter til det sikre skrivebord, gør det til det nuværende, så input er nu forbundet med det.


Det gamle skrivebord forbliver, hvor det var: alle HWND'er på skrivebordet er stadig der, og enhver tråd, der er knyttet til skrivebordet, kan stadig få adgang til disse HWND'er, få deres placering osv. Du kan stadig sende beskeder til Windows på dette skrivebord, så længe tråden, der sender meddelelsen, også findes på skrivebordet.


Men da skrivebordet nu er inaktivt, kan det ikke modtage input. GetForegroundWindow returnerer NULL (IIRC), og du kan ikke bruge SendInput længere, da input nu tilhører [[en tråd på]] et andet skrivebord, ingen kontroller på det inaktive skrivebord kan modtage fokus.


Bemærk, at afsendelse af tastetrykbeskeder til en kontrol, der ikke har fokus, kan nogle gange forårsage uventet opførsel, da appen eller kontrollen generelt aldrig forventer at modtage tastaturindgang uden at fokusere først. (Dette kan være problematisk for kontroller, der er oprettet som en slags af input kontekst i WM\_SETFOCUS og rydde den op i WM\_KILLFOCUS, for eksempel.)


Kort sagt er brugergrænsefladen stadig der: Du kan gøre visse forespørgsler imod det, men du kan ikke automatisere det som du kunne på et almindeligt skrivebord ved at sende input, og nogle andre funktioner, der vedrører fokus eller input, kan mislykkes.


Jeg er ikke super bekendt med AutoHotKey, men navnet og beskrivelsen af ​​funktionalitet tyder på, at den er stærkt afhængig af den underliggende Win32 SendInput API. Dette virker slet ikke for tastaturindgang, når et skrivebord er inaktivt.


For et fornuftigt overblik over, hvordan desktops fungerer, og hvordan de vedrører winstations, det låste skrivebord og så videre, tjek Desktopartikel på MSDN .


Et problem, som jeg tidligere har haft med desktop og automation, er: hvordan jeg laver en langvarig test, der bruger en form for brugerinputautomatisering (mus, tastatur simulering), men stadig låse min pc så man kan ikke bare gå igennem og forstyrre den. Når du låser pc'en, er skrivebordet inaktiv, og derfor standser automatikken ikke. Et lignende problem sker, hvis screensaveren skifter ind: skrivebordet skifter, og automationen fejler.


En løsning er at bruge to pc'er: Lad dem kalde dem Main og Test: fra Main, åbner en fjernbetjeningsklient på testmaskinen, og kør derefter den automatiske test på testmaskinen, men fra et terminal-klientvindue på Main-maskinen. Nu er den kølige del: Du kan minimere det TSC-vindue, eller endda låse hovedmaskinen (eller lad skærmeskærmen sparke ind), og den virtuelle session vil fortsætte med at arbejde og tænker at den stadig er aktiv - det er bare at ingen betaler det nogen opmærksomhed. Dette er en måde at oprette en 'tilsluttet' session med et aktivt skrivebord, men en, som ingen kan forstyrre, fordi den er beskyttet bag hovedmaskinens låste skrivebord.

Andre referencer 1


Jeg kender ikke detaljerne, men jeg tror, ​​at låseskærmen udgør en separat 'desktop' og måske også en separat 'vinduestation' (som jeg forstår, at en vinduestation kun er en beholder til desktops). MSDN-sektionen på vinduet Stationer skal forhåbentlig være nyttige: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687098\%28v=vs.85\%29.aspx[3]


For at få adgang til et skrivebord skal du bruge de almindelige Windows-api fra en tråd, der er på skrivebordet. SetThreadDesktop ville nok være den nemmeste måde at gøre det i C, så længe skrivebordet ikke er på en desktop forskellige vinduestation.


Desværre er dette allerede svært for en regelmæssig privilegeret applikation, og ved hjælp af AutoHotkey kompliceres det endnu mere. Da du ikke har kontrol over tråde eller over procesinitialisering, skal du sandsynligvis lave en ny proces på det andet skrivebord (du kan gøre dette ved hjælp af CreateProcess API, der ser ud til at have en indpakning tilgængelig for AHK, som du kan levere et desktop navn: http://www.autohotkey.com/forum/topic1952.html). Din proces vil have særlige privilegier til at gøre dette; jeg er ikke sikker på at selv kører som administrator er nok. [4]