Zapobieganie kradzieży aplikacji

191

Czy istnieją jakieś rozwiązania zapobiegające kradzieży aktywności przez aplikacje z aktywnego okna?

Jest to szczególnie denerwujące, kiedy uruchamiam aplikację, przełącz się na coś innego, a nowa aplikacja zacznie otrzymywać pół zdania tekstu.

svandragt
źródło
9
@Ivo Windows 7 w moim przypadku, ale myślę, że w przypadku SuperUser wszystkie wersje systemu Windows byłyby odpowiednie
svandragt
3
Moderator połączył to pytanie: superuser.com/questions/199821/... z bieżącym. To źle, odpowiedź na bieżące pytanie nie dotyczy systemu Windows 7, więc nie należy go scalać. Do tej pory nie mogłem znaleźć rozwiązania tego problemu w systemie Windows 7
Alex Angelico,
17
Jest to jeden z moich ulubionych artykułów dla zwierząt w każdym GUI, którego kiedykolwiek używałem. Piszesz i obwiniasz, niektóre wyblakłe okno dialogowe kradnie fokus, a połowa naciśnięć klawiszy idzie gdzie indziej. Można by pomyśleć, że realizatorzy systemów okienkowych zorientowaliby się tego kilkadziesiąt lat temu. Jeśli w oknie jest aktywność, opóźnij ekspozycję nowego okna. Np. Nie wyświetlaj niczego w GUI przez trzy lub cztery sekundy od ostatniego kliknięcia przycisku lub naciśnięcia klawisza w aktualnie zaznaczonym oknie. Doh!
Kaz
24
This is especially annoying when I'm starting an application, switch to do something else and the new application starts receiving half a sentence of text.Jeszcze bardziej irytujące jest pojawienie się okna dialogowego, które nieumyślnie odrzucasz, nawet nie widząc wiadomości, ponieważ zdarzyło Ci się naciskać Spacelub Enterpisać zdanie.
Synetech
3
Jest to w rzeczywistości o wiele bardziej irytujące, powiedziałbym, że to ryzyko dla bezpieczeństwa. Nic nie stoi na przeszkodzie, aby aplikacja wyskakiwała, gdy jesteś w trakcie wpisywania hasła i pobierania danych wejściowych.
Chris Peacock,

Odpowiedzi:

51

Nie jest to możliwe bez obszernej manipulacji wewnętrznymi elementami systemu Windows i trzeba się z tym pogodzić.

Są chwile w codziennym korzystaniu z komputera, kiedy naprawdę ważne jest, aby wykonać jedną akcję, zanim system operacyjny pozwoli na wykonanie innej. Aby to zrobić, musisz zablokować koncentrację na niektórych oknach. W systemie Windows kontrola nad tym zachowaniem jest w dużej mierze pozostawiona twórcom poszczególnych używanych programów.

Nie każdy programista podejmuje właściwe decyzje, jeśli chodzi o ten temat.

Wiem, że jest to bardzo frustrujące i denerwujące, ale nie możesz też zjeść ciasta. Prawdopodobnie w twoim codziennym życiu jest wiele przypadków, w których wszystko jest w porządku, gdy fokus jest przenoszony do określonego elementu interfejsu użytkownika lub aplikacji żądającej, aby fokus pozostał na nim zablokowany. Ale większość aplikacji jest nieco równa, jeśli chodzi o decydowanie, kto jest teraz liderem, a system nigdy nie będzie doskonały.

Jakiś czas temu przeprowadziłem szeroko zakrojone badania nad rozwiązaniem tego problemu raz na zawsze (i nie udało się). Wyniki moich badań można znaleźć na stronie projektu irytującego .

Projekt obejmuje również aplikację, która wielokrotnie próbuje skupić się, wywołując:

switch( message ) {
  case WM_TIMER:
    if( hWnd != NULL ) {
      // Start off easy
      // SetForegroundWindow will not move the window to the foreground,
      // but it will invoke FlashWindow internally and, thus, show the
      // taskbar.
      SetForegroundWindow( hWnd );

      // Our application is awesome! It must have your focus!
      SetActiveWindow( hWnd );

      // Flash that button!
      FlashWindow( hWnd, TRUE );
    }
    break;

Jak widać z tego fragmentu, moje badania skupiły się również na innych aspektach zachowania interfejsu użytkownika, które mi się nie podobają.

Próbowałem rozwiązać ten problem, ładując bibliotekę DLL do każdego nowego procesu i przechwytując wywołania API, które powodują aktywację kolejnych okien.
Ostatnia część jest łatwa dzięki niesamowitym bibliotekom przechwytującym API. Użyłem bardzo dobrej biblioteki mhook :

#include "stdafx.h"
#include "mhook-2.2/mhook-lib/mhook.h"

typedef NTSTATUS( WINAPI* PNT_QUERY_SYSTEM_INFORMATION ) ( 
  __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,     
  __inout    PVOID SystemInformation, 
  __in       ULONG SystemInformationLength, 
  __out_opt  PULONG ReturnLength    
);

// Originals
PNT_QUERY_SYSTEM_INFORMATION OriginalFlashWindow   = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "FlashWindow" );

PNT_QUERY_SYSTEM_INFORMATION OriginalFlashWindowEx = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "FlashWindowEx" );

PNT_QUERY_SYSTEM_INFORMATION OriginalSetForegroundWindow = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "SetForegroundWindow" );

// Hooks
BOOL WINAPI
HookedFlashWindow(
  __in  HWND hWnd,
  __in  BOOL bInvert
  ) {
  return 0;
}

BOOL WINAPI 
HookedFlashWindowEx(
  __in  PFLASHWINFO pfwi
  ) {
  return 0;
}

BOOL WINAPI 
HookedSetForegroundWindow(
  __in  HWND hWnd
  ) {
  // Pretend window was brought to foreground
  return 1;
}


BOOL APIENTRY 
DllMain( 
  HMODULE hModule,
  DWORD   ul_reason_for_call,
  LPVOID  lpReserved
  ) {
  switch( ul_reason_for_call ) {
    case DLL_PROCESS_ATTACH:
      Mhook_SetHook( (PVOID*)&OriginalFlashWindow,         HookedFlashWindow );
      Mhook_SetHook( (PVOID*)&OriginalFlashWindowEx,       HookedFlashWindowEx );
      Mhook_SetHook( (PVOID*)&OriginalSetForegroundWindow, HookedSetForegroundWindow );
      break;

    case DLL_PROCESS_DETACH:
      Mhook_Unhook( (PVOID*)&OriginalFlashWindow );
      Mhook_Unhook( (PVOID*)&OriginalFlashWindowEx );
      Mhook_Unhook( (PVOID*)&OriginalSetForegroundWindow );
      break;
  }
  return TRUE;
}

Z moich ówczesnych testów to działało świetnie. Z wyjątkiem części ładowania biblioteki DLL do każdego nowego procesu. Jak można sobie wyobrazić, nie można tego lekceważyć. Użyłem wtedy metody AppInit_DLLs (co po prostu nie jest wystarczające).

Zasadniczo działa to świetnie. Ale nigdy nie znalazłem czasu, aby napisać coś, co odpowiednio wstrzykuje moją bibliotekę DLL do nowych procesów. A czas zainwestowany w to w dużej mierze przesłania irytację, którą wywołuje u mnie kradzież ogniskowej.

Oprócz problemu z wstrzykiwaniem biblioteki DLL istnieje również metoda kradzieży ostrości, której nie omawiałem przy implementacji kodu Google. Współpracownik faktycznie przeprowadził dodatkowe badania i omówił tę metodę. Problem został omówiony na SO: https://stackoverflow.com/questions/7430864/windows-7-prevent-application-from-losing-focus

Der Hochstapler
źródło
Czy uważasz, że to twoje rozwiązanie można przenieść na Javę? Szukałem i zadawałem pytania, ale nic nie znalazłem. Może mógłbym zaimportować samą bibliotekę hooków do java jne?
Tomáš Zato
@ TomášZato: Nie mam pojęcia. Nie aktywnie korzystam z tego kodu.
Der Hochstapler,
Próbuję skompilować go przynajmniej jako C ++ (a następnie wstrzyknąć / usunąć skompilowaną bibliotekę DLL z Javy). Ale to też nie idzie dobrze. Nie chcę omawiać tego tutaj w komentarzach, ale jeśli mógłbyś mi pomóc w uruchomieniu go, byłbym bardzo wdzięczny! Stworzyłem pokój czatu, jeśli dostanę to do pracy, opublikuję komentarz, jak to zrobić tutaj: chat.stackexchange.com/rooms/21637/...
Tomáš
23

W systemie Windows 7 ForegroundLockTimeoutwpis rejestru nie jest już sprawdzany, można to sprawdzić za pomocą Monitora procesów. W rzeczywistości w systemie Windows 7 uniemożliwiają zmianę okna pierwszego planu. Idź i przeczytaj o jego szczegółach , jest tam nawet od Windows 2000.

Jednak dokumentacja jest do kitu, a oni gonią się nawzajem i szukają sposobów na obejście tego .

Jest więc coś nie tak z błędami SetForegroundWindowlub podobnymi funkcjami API ...

Jedynym sposobem, aby naprawdę to zrobić poprawnie, jest utworzenie małej aplikacji, która okresowo wywołuje LockSetForegroundWindow, praktycznie wyłączając wszelkie połączenia z naszą błędną funkcją API.

Jeśli to nie wystarczy (kolejne błędne wywołanie API?), Możesz pójść jeszcze dalej i wykonać monitorowanie API, aby zobaczyć, co się dzieje, a następnie po prostu zaczepisz wywołania API na każdym procesie, po którym możesz pozbyć się wszelkich wywołujących problemy pierwszy plan. Jak na ironię Microsoft nie odradza tego ...

Tamara Wijsman
źródło
3
Czy ktoś ma powtarzalny przypadek użycia tego w Windows 7? Biorąc pod uwagę, że ludzie raczej doświadczają czegoś przeciwnego (na przykład często uważam, że wymagający system Windows jest ukryty za moim obecnym oknem) i że mam się jeszcze tego spodziewać w Windows 7, napisanie aplikacji byłoby dość denerwujące, ale nie mogłem Sprawdź to. Co więcej, jak twierdzi Microsoft, nie powinno to się już zdarzyć w systemie Windows 7. W najlepszym wypadku ludzie odkryli, że może przypadkowo przełączyć się na klawiaturę, to wywołanie interfejsu API naprawiłoby to, ale nie wiem, jak sprawdzić, czy to naprawdę działa. .
Tamara Wijsman
1
Instalator (oparty na InnoSetup) uruchamia inne procesy i możliwe inne (ukryte) konfiguracje, ale nie wiem, na czym opiera się kreator instalacji.
Daniel Beck
6
@TomWijsman: Otwórz regedit, wyszukaj losowy tekst, który nie zostanie znaleziony. Przejdź do innej aplikacji i zacznij pisać. Po zakończeniu wyszukiwania regedit wykradnie fokus.
endolith
1
@endolith: Nie można go odtworzyć, używając tutaj Windows 8 Replase Preview. Z jakiego systemu operacyjnego korzystasz? W moim przypadku po prostu podświetla aplikację na dole, ale wcale nie przerywa przeglądania ...
Tamara Wijsman,
21
Tak, Win7 Pro 64-bit. A kradzież ostrości jest jeszcze gorsza w przypadku procesów o podwyższonym poziomie, ponieważ wychwytują naciśnięcie klawisza <Enter>, gdy nie powinny, a ty każesz mu przypadkowo podłączyć system. Nic nigdy nie powinno być w stanie ukraść skupienia.
endolith
18

Istnieje opcja w TweakUI, która to robi. Zapobiega większości typowych sztuczek, których używają podejrzani programiści, aby skupić się na swojej aplikacji.

Trwa jednak wojna zbrojeniowa, więc nie wiem, czy to działa na wszystko.

Aktualizacja : Według EndangeredMassa TweakUI nie działa w systemie Windows 7.

Simon P. Stevens
źródło
2
czy tweakui jest kompatybilny z Windows 7?
frankster
@frankster. Nie mam pojęcia, przepraszam, podejrzewam, że prawdopodobnie nie jest. Pobierz i wypróbuj. Zgłoś się, jeśli to zrobisz, wszyscy to wiedzą.
Simon P. Stevens,
5
Nawet przy użyciu ustawienia rejestru ustawionego przez TweakUI nie działa na Win7.
EndangeredMassa
@EndangeredMassa, który to klucz rejestru?
n611x007
2
Klucz rejestru to HKEY_CURRENT_USER \ Control Panel \ Desktop \ ForegroundLockTimeout (w milisekundach). I tak, nie działa już w systemie Windows 7.
foo
14

Uważam, że mogą wystąpić pewne nieporozumienia, ponieważ istnieją dwa sposoby „kradzieży fokusa”: (1) okno wychodzące na pierwszy plan i (2) okno odbierające naciśnięcia klawiszy.

Problem, o którym tu mowa, jest prawdopodobnie drugi, w którym okno przejmuje fokus, przenosząc się na pierwszy plan - bez prośby i zgody użytkownika.

Dyskusja musi zostać podzielona między XP i 7.

Windows XP

W XP występuje hack rejestru, który sprawia, że ​​XP działa tak samo jak Windows 7, zapobiegając kradzieży aplikacji:

  1. Użyj regedit, aby przejść do: HKEY_CURRENT_USER\Control Panel\Desktop.
  2. Kliknij dwukrotnie ForegroundLockTimeouti ustaw jego wartość w systemie szesnastkowym na 30d40.
  3. Naciśnij OK i wyjdź z regedit.
  4. Uruchom ponownie komputer, aby zmiany odniosły skutek.

System Windows 7

(Poniższa dyskusja dotyczy głównie także XP).

Proszę zrozumieć, że nie ma sposobu, w jaki system Windows może całkowicie zablokować aplikacje przed kradzieżą ostrości i zachować funkcjonalność. Na przykład, jeśli podczas kopiowania pliku program antywirusowy wykrył potencjalne zagrożenie i chciałby wyświetlić okno z prośbą o podjęcie działania, jeśli to okno jest zablokowane, nigdy nie zrozumiesz, dlaczego kopia nigdy się nie kończy.

W systemie Windows 7 możliwa jest tylko jedna modyfikacja zachowania samego systemu Windows, polegająca na użyciu hakerów rejestru MS-Windows Registry-follow-mouse , w których fokus i / lub aktywacja zawsze odbywa się w oknach pod kursorem. Można dodać opóźnienie, aby uniknąć wyskakiwania aplikacji na całym pulpicie.
Zobacz ten artykuł: Windows 7 - Najechanie myszą sprawia, że ​​okno jest aktywne - Włącz .

W przeciwnym razie należy wykryć i zneutralizować winny program: jeśli zawsze jest to ta sama aplikacja, która się skupia, wówczas ta aplikacja jest zaprogramowana na przejmowanie ostrości i można temu zapobiec poprzez wyłączenie go z komputera lub użyj niektórych ustawień dostarczonych przez tę aplikację, aby uniknąć tego zachowania.

Możesz użyć skryptu VBS zawartego w kodzie VB, który identyfikuje, kto skupia się na kradzieży , którego autor użył do zidentyfikowania winowajcy jako narzędzia do aktualizacji oprogramowania drukarki.

Zdesperowanym środkiem, gdy wszystko inne zawiedzie, a jeśli zidentyfikujesz tę źle zaprogramowaną aplikację, jest jej zminimalizowanie i nadzieja, że ​​nie przejdzie ona na pierwszy plan. Silniejszą formą minimalizacji jest taca, używając jednego z bezpłatnych produktów wymienionych w Best Free Application Minimizer .

Ostatnim pomysłem w kolejności desperacji jest złamanie pulpitu wirtualnie za pomocą produktu takiego jak Desktops lub Dexpot i wykonywanie pracy na innym pulpicie niż domyślny.

[EDYTOWAĆ]

Ponieważ Microsoft wycofał się z Galerii Archiwum, oto odtworzony powyżej kod VB:

Declare Auto Function GetForegroundWindow Lib "user32.dll" () As Integer
Declare Auto Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Integer, ByRef procid As Integer) As UInteger

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.RichTextBox1.AppendText("Starting up at " & Now & vbCrLf)
    End Sub

    Private Sub GoingAway(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate, Me.LostFocus

        Dim hwnd As Integer = GetForegroundWindow()
        ' Note that process_id will be used as a ByRef argument
        ' and will be changed by GetWindowThreadProcessId
        Dim process_id As Integer = 1
        GetWindowThreadProcessId(hwnd, process_id)

        If (process_id <> 1) Then
            Dim appExePath As String = Process.GetProcessById(process_id).MainModule.FileName() 
            Me.RichTextBox1.AppendText("Lost focus at " & Now & " due to " & appExePath & vbCrLf)
        Else
            Me.RichTextBox1.AppendText("Lost focus due to unknown cause.")
        End If

    End Sub
harrymc
źródło
48
„jeśli to okno jest zablokowane, nigdy nie zrozumiesz, dlaczego kopia nigdy się nie kończy” To nieprawda. Prawidłowym zachowaniem jest powiadomienie użytkownika migającą ikoną paska zadań (lub wyskakujące okienko z balonem, powiadomienie tostera lub coś takiego). Przerwanie przez użytkownika okna, które przechwytuje ich naciśnięcia klawiszy, oznacza, że ​​informuje oprogramowanie antywirusowe o losowej akcji. Zdecydowanie nie jest to dobry sposób na robienie różnych rzeczy.
endolith
1
„jeśli to okno jest zablokowane, nigdy nie zrozumiesz, dlaczego kopia nigdy się nie kończy” To nieprawda. Prawidłowe zachowanie polega na powiadomieniu użytkownika migającą ikoną paska zadań ... Kiedyś kliknąłem przycisk lub coś w uruchomionym programie, co powoduje utworzenie nowego modalnego okna dialogowego (np. Otwarcie pliku ), ale potem Przed utworzeniem okna dialogowego przełączam się na inny program. W wyniku tego okno dialogowe jest ukryte, a drugiego programu nie można przełączyć i okna dialogowego nie można zamknąć. Ani przycisk paska zadań, ani nie Alt-Tabdziała; tylko zmuszając okno dialogowe do przodu.
Synetech,
1
@Synetech: Czasami jedynym rozwiązaniem w oknie dialogowym innym niż front jest zabicie zadania. Algorytmy ustawiania ostrości w systemie Windows są naprawdę kiepskie.
harrymc
2
@harrymc, nigdy nie muszę uciekać się do zabicia jednej z aplikacji. Po prostu uruchamiam mój program do manipulowania oknami ( WinSpy ++ świetnie sobie radzi) i chowam okno z przodu, potem mogę zamknąć okno dialogowe zablokowania, a następnie ponownie pokazać ukryte okno. Nie jest to wygodne, ale jest lepsze niż zabicie jednego z procesów.
Synetech,
1
@harrymc, niezupełnie; zabicie aplikacji i utrata rzeczy powoduje tylko wzrost pary, a jeśli jest to modalne okno dialogowe (które blokuje okno nadrzędne i nie ma przycisku paska zadań), to nie pojawi się na Alt+Tabliście, a moim zdaniem okno, które ma otwarte modalne okno dialogowe nie zawsze (nigdy?) pokazuje modalne okno dialogowe Alt+Tab, szczególnie jeśli okno dialogowe nigdy nie miało zmiany, aby uzyskać fokus. :-|
Synetech,
2

Ghacks ma możliwe rozwiązanie:

Zdarza się kilka razy dziennie, że niektóre aplikacje wykradają fokus aktywnego okna, wyskakując. Może się to zdarzyć z wielu powodów, na przykład gdy rozpakuję pliki lub transfer zostanie zakończony. Przez większość czasu to nie ma znaczenia, ale czasami piszę artykuł i nie tylko oznacza to, że muszę ponownie wpisać kilka słów, ale także, że straciłem koncentrację i muszę kliknąć, aby odzyskać koncentrację.

Pro recenzent strona ma wskazówka, jak temu zapobiec. Najłatwiejszym sposobem zapobiegania kradzieży fokusa jest użycie interfejsu Tweak, który ma ustawienie „Zapobieganie kradzieży fokusu przez aplikacje”. Zaznaczenie tej opcji zapobiega gwałtownemu wyskakiwaniu innych aplikacji i kradzieży okna, w którym aktualnie pracujesz.

Działa to tylko wtedy, gdy aplikacja została wcześniej zminimalizowana. Zamiast kradnąć fokus, mignie kilka razy, co można zdefiniować w tym samym menu w Tweak UI . Jeśli nie chcesz korzystać z interfejsu Tweak, możesz zmienić ustawienie w rejestrze systemu Windows.

Przejdź do klucza rejestru HKEY_CURRENT_USER> Panel sterowania> Pulpit i zmień wartość ForegroundLockTimeout na 30d40 (szesnastkowo) lub 200000 (dziesiętnie). Klucz ForeGroundFlashCount określa liczbę błysków okna, aby ostrzec użytkownika, gdzie 0 oznacza nieograniczoną liczbę.

Ivo Flipse
źródło
20
To nie działa na żadnym systemie operacyjnym po XP. Ta wartość rejestru jest już ustawiona (domyślnie, jak sądzę) i i tak nie działa.
EndangeredMassa
1
Zaraz na sekundę, że jestem w systemie Windows 7 (64-bitowym), mam kradzież ostrości (VS 2012, kiedy wreszcie jest aktywny, na przykład), a powyższa sugestia rejestru jest już na miejscu. Potwierdzenie techniczne w tej odpowiedzi: superuser.com/a/403554/972
Michael Paulukonis
2

Zainspirowany odpowiedzią Der Hochstapler postanowiłem napisać iniektor DLL, który działa zarówno z procesami 64-bitowymi, jak i 32-bitowymi i zapobiega kradzieży fokusu w systemie Windows 7 lub nowszym: https://blade.sk/stay-focused/

Działa w ten sposób, że obserwuje nowe okna (używając SetWinEventHook) i wstrzykuje DLL bardzo podobny do Der Hochstaplera do procesu okna, jeśli jeszcze nie jest obecny. Zwalnia biblioteki DLL i przywraca oryginalną funkcjonalność przy wyjściu.

Z moich testów do tej pory działa bardzo dobrze. Wydaje się jednak, że problem jest głębszy niż tylko dzwonienie do aplikacji SetForegroundWindow. Na przykład, gdy tworzone jest nowe okno, jest ono automatycznie przenoszone na pierwszy plan, co również przeszkadza użytkownikowi piszącemu w innym oknie.

Aby poradzić sobie z innymi metodami kradzieży fokusu, wymagane są dalsze testy i byłbym wdzięczny za wszelkie opinie na temat scenariuszy, w których to się dzieje.

nóż
źródło
0

Wymyśliłem, jak powstrzymać pasek zadań przed flashowaniem nowo aktywowanego okna docelowego po programowej aktywacji, maksymalizacji i skupieniu głównego okna tego procesu z innego procesu. Przede wszystkim istnieje wiele ograniczeń, czy ta operacja będzie dozwolona.

„System ogranicza, które procesy mogą ustawić okno na pierwszym planie. Proces może ustawić okno na pierwszym planie tylko wtedy, gdy spełniony jest jeden z następujących warunków:

  • Proces jest procesem na pierwszym planie.
  • Proces rozpoczął się od pierwszego planu.
  • Proces odebrał ostatnie zdarzenie wejściowe.
  • Nie ma procesu pierwszoplanowego.
  • Proces pierwszego planu jest debugowany.
  • Pierwszy plan nie jest zablokowany (patrz LockSetForegroundWindow).
  • Upłynął limit czasu blokady pierwszego planu (patrz SPI_GETFOREGROUNDLOCKTIMEOUT w SystemParametersInfo).
  • Brak aktywnych menu.

https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-allowsetforegroundwindow

Jeśli więc proces sterujący znajduje się na pierwszym planie, może tymczasowo umożliwić innym procesom pełne kradzież pierwszego planu, wywołując AllowSetForegroundWindow z identyfikatorem procesu docelowego. Następnie proces docelowy może wywołać samą SetForegroundWindow , używając własnego uchwytu okna, i będzie działać.

Oczywiście wymaga to pewnej koordynacji między dwoma procesami, ale działa, a jeśli robisz to, aby zaimplementować aplikację z pojedynczą instancją, która przekierowuje wszystkie uruchomienia kliknięcia Eksploratora do istniejącej instancji aplikacji, to już będziesz mieć (np.) nazwany potok, aby mimo wszystko koordynować rzeczy.

Glenn Slayden
źródło