Autor Wątek: [WinApi]Kliknięcie przycisku w innej aplikacji  (Przeczytany 3637 razy)

Offline krzyfn

  • Użytkownik

# Październik 18, 2010, 20:52:44
Tworzę aplikację w C#, która automatyzuje pewne procesy.
Chcę obsłużyć następujące okienko:



Za pomocą funkcji FindWindow:
http://msdn.microsoft.com/en-us/library/ms633499%28v=VS.85%29.aspx

uzyskuję uchwyt do tego okna. Teraz chciałbym przy użyciu funkcji SendDlgItemMessage:
http://msdn.microsoft.com/en-us/library/ms645515%28v=VS.85%29.aspx

wysłać do tego okna kliknięcie odpowiedniego przycisku. Niestety nie posiadam numerów ID tych przycisków i nie bardzo wiem jak je poznać. Czy ktoś wie co zrobić, aby poznać numery ID tych kontrolek? Albo może ktoś ma pomysł jak za pomocą WinApi obsłużyć kliknięcie jednego z przycisków?
Numery tych kontrolek, to na pewno nie 0, 1, 2...

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Kos

  • Użytkownik
    • kos.gd

# Październik 18, 2010, 21:12:34
Niech mnie, jeśli się da. :)

Offline krzyfn

  • Użytkownik

# Październik 18, 2010, 21:14:08
No skoro jest funkcja "SendDlgItemMessage" która jako parametr przyjmuje uchwyt do okna, ID kontrolki i wiadomość którą chcemy do tej kontrolki wysłać, to chyba jakoś się da co?

Wyczytałem coś ciekawego tutaj:
http://msdn.microsoft.com/en-us/library/bb775494%28v=VS.85%29.aspx#Common_Control_Messages

Controls are child windows that send notification messages to the parent window when events, usually triggered by input from the user, occur in the control.

O ile dobrze to rozumiem, to znaczy że kontrolki takie jak 'button', 'label', etc. są po prostu 'child windows', a to oznacza że można się do nich dobrać np. przy pomocy 'EnumChildWindows' - swoją drogą dość zawikłana funkcja...
« Ostatnia zmiana: Październik 18, 2010, 21:19:47 wysłana przez krzyfn »

Offline Kos

  • Użytkownik
    • kos.gd

# Październik 18, 2010, 21:20:26
Cóż, wydaje mi się, że w czasach Windows 7 w MS poleciałyby głowy za zabezpieczenie, które można obejść prostym SendDlgItemMessage.

Ale jakby Ci się udało, to od razu możesz z rozpędu obejść w taki sam sposób ostrzeżenia UAC i przywrócić erę nawału wirusów na Windowsach. Sprytne... Aż dziw, że też nikt jeszcze nie spróbował, nie? :)

Offline krzyfn

  • Użytkownik

# Październik 18, 2010, 22:19:00
Nie do końca rozumiem co masz na myśli, ale jeśli chodzi o ingerowanie w zawartość okienek, to praktycznie wszechmogący jest ahk, który można kompilować do plików *.exe. Jeśli nie uda mi się tego zrobić za pomocą WinApi, to wyklikam sobie w ahk, jednak to nie jest zgodne z sztuką programowania, skoro główna aplikacja jest w C#.

Offline Kos

  • Użytkownik
    • kos.gd

# Październik 18, 2010, 23:30:01
Hm. "praktycznie wszechmogący" as in "wiadomo, że da się nim ingerować w systemowe alerty bezpieczeństwa"?

Sprawa jest taka: Jeśli systemowe alerty bezpieczeństwa da się zatwierdzić programatycznie, to jest to bug w systemie (i nie powinieneś go wykorzystywać, dopóki nie piszesz exploita :)). Żyję w nadziei, że Win7 jest na tyle bezpieczny, że żaden z nas tego nie obejdzie.

Offline Xirdus

  • Redaktor

# Październik 18, 2010, 23:41:50
Jeśli ta aplikacja działa, to nic nie jest bezpieczne.

Offline Kos

  • Użytkownik
    • kos.gd

# Październik 18, 2010, 23:44:54
Jeśli ta aplikacja działa, to nic nie jest bezpieczne.
Taaa? :) To spróbuj odpalić cokolwiek z prawami admina i jak wyskoczy alert UPC, to kliknij w "yes" tym swoim magicznym autoklikającym programem. Ups? :>

mwahahah, uwielbiam mieć rację :> ale dzięki za link, idę bić rekordy w grze Xirdusa >_>
« Ostatnia zmiana: Październik 18, 2010, 23:48:14 wysłana przez Kos »

Offline krzyfn

  • Użytkownik

# Październik 19, 2010, 00:38:38
No dobra, ale odeszliśmy od meritum. Tu nie chodzi o żadne bezpieczeństwo, tylko pozbycie się głupiego okienka, które do niczego nie jest potrzebne, a na systemie Vista x64 jest taki bug, że pomimo wyłączenia sprawdzania podpisów to okienko i tak się pojawia.
Jeszcze jakieś pomysły jak się go pozbyć przy użyciu C#?

Offline Kos

  • Użytkownik
    • kos.gd

# Październik 19, 2010, 00:45:01
Nie odeszliśmy od meritum. Wniosek jest prosty: nie da się, nie należy, odpuść. Sama Twoja chęć zrobienia tego jest błędna. Zastanów się nad sobą! :)

Offline sqrczybyk

  • Użytkownik

# Październik 19, 2010, 13:47:38
IntPtr syn = WinAPI.GetWindow(ojciec, WinAPI.GW_CHILD);
IntPtr nastepnySyn = WinAPI.GetWindow(syn, WinAPI.GW_HWNDNEXT);
Ale Kos dobrze radzi, nie rób tego^^.

Offline blizniak

  • Użytkownik

# Październik 19, 2010, 14:36:27
spokojnie możesz użyć AHK do tego jak najbardziej daje radę (widziałem skrypt w AHK który klikał dokładnie w takie okienko).

co do podglądania ID przycisków użyj Spy++ (standardowo z MSVC++) - proponuję odszukiwać buttony po ich "caption" lub czymś takim - wtedy możesz wyszukać taki child window (przycisk jest jak najbardziej okienkiem) i wysyłać mu wiadomość kliknięcia

Offline krzyfn

  • Użytkownik

# Październik 20, 2010, 00:27:19
No tak, tylko idealnym scenariuszem byłoby dopisanie fragmentu kodu w C# do już istniejącej sporej aplikacji, bez dodatkowych kombinacji (jak np. AHK, Spy++, etc.), dlatego zależy mi na tym, aby zrobić to w czystym WinApi.
Dlaczego 'nie rób tego', skoro potrzebuję takiego klikadła, aby ułatwiło mi życie?
Jutro przetestuję propozycję sqrczybyka i sprawdzę jak się sprawuje funkcja EnumChildWindows.
« Ostatnia zmiana: Październik 20, 2010, 00:30:06 wysłana przez krzyfn »

Offline sqrczybyk

  • Użytkownik

# Październik 20, 2010, 00:42:35
Chyba już masz wszystko co potrzeba... FindWindow wyszukujesz okna z belką tytułową. Napisałem jak dobrać się do dzieci, czyli kontrolek których szukasz. Jeśli są to zwykłe buttony, to powinno zadziałać: WinAPI.SendMessage(uchwytPrzycisku, WinAPI.BM_CLICK, IntPtr.Zero, IntPtr.Zero);

Offline krzyfn

  • Użytkownik

# Październik 20, 2010, 14:12:41
Niestety:
IntPtr syn = WinAPI.GetWindow(ojciec, WinAPI.GW_CHILD);
IntPtr nastepnySyn = WinAPI.GetWindow(syn, WinAPI.GW_HWNDNEXT);
zwraca pusty wskaźnik, co by znaczyło, że te przyciski nie są 'child windows'