Câu hỏi Ngăn chặn các ứng dụng lấy cắp tập trung


Có bất kỳ giải pháp nào để ngăn chặn các ứng dụng lấy cắp tiêu điểm từ cửa sổ đang hoạt động không?

Điều này đặc biệt khó chịu khi tôi bắt đầu một ứng dụng, chuyển sang làm điều gì khác và ứng dụng mới bắt đầu nhận được một nửa câu văn bản.


174
2017-08-05 08:48


gốc


@ Ivo Windows 7 trong trường hợp của tôi nhưng tôi nghĩ cho SuperUser tất cả các phiên bản windows sẽ có liên quan - svandragt
Người kiểm duyệt đã hợp nhất câu hỏi này: superuser.com/questions/199821/… với cái hiện tại. Điều này là sai, câu trả lời cho câu hỏi hiện tại không áp dụng cho windows 7, vì vậy nó không nên được sáp nhập. Cho đến nay tôi không thể tìm thấy một giải pháp cho vấn đề này trong Windows 7 - Alex Angelico
Đây là một trong những con vật cưng số một của tôi với mọi GUI mà tôi từng sử dụng. Bạn đang gõ và blam, một số hộp thoại bleeping đánh cắp tập trung và một nửa tổ hợp phím của bạn đi một nơi khác. Bạn sẽ nghĩ rằng những người triển khai hệ thống cửa sổ sẽ tìm ra cách này từ nhiều thập kỷ trước. Nếu có hoạt động trong cửa sổ, hãy trì hoãn hiển thị cửa sổ mới. Ví dụ. không bật bất cứ thứ gì lên trên GUI cho đến ba hoặc bốn giây kể từ lần nhấp nút hoặc lần nhấn phím cuối cùng trong cửa sổ hiện đang được tập trung. Doh! - Kaz
tôi tìm thấy khi tôi có ổ cứng gắn ngoài (được Seagate) hoặc iPod nano (ahem, apple) kết nối với máy tính Windows 7 của tôi, nó sẽ xuất hiện "máy tính để bàn" sẽ lấy nét mỗi 30 giây hoặc lâu hơn, từ những gì tôi đã duyệt, có thể là âm nhạc itunes, kết quả tìm kiếm Chrome hoặc email firefox. Tôi đã tắt tính năng tự động phát và điều đó đã giúp một lúc, nhưng sự cố đã trở lại ngay cả sau khi tự động phát bị tắt. Tôi đoán tôi phải giữ bên ngoài của tôi HD và ổ đĩa flash bị ngắt kết nối cho hầu hết các phần, mà hút cuz thats nơi mà tất cả âm nhạc của tôi là: (Đó là một lỗi thực sự gây phiền nhiễu mà làm cho tôi muốn S
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.Thậm chí còn khó chịu hơn khi một hộp thoại bật lên và bạn vô tình bỏ qua nó mà không hề thấy thông báo vì bạn đã từng nhấn Space hoặc là Enter trong khi gõ một câu. - Synetech


Các câu trả lời:


Một thời gian trước, tôi đã nghiên cứu sâu rộng về giải quyết vấn đề này một lần và cho tất cả (và thất bại). Kết quả nghiên cứu của tôi có thể được tìm thấy trên trang dự án gây phiền nhiễu.

Dự án cũng bao gồm một ứng dụng liên tục cố gắng lấy nét bằng cách gọi:

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;

Như chúng ta có thể thấy từ đoạn mã này, nghiên cứu của tôi cũng tập trung vào các khía cạnh khác của hành vi giao diện người dùng mà tôi không thích.

Cách tôi đã cố gắng để giải quyết điều này là để tải một DLL vào mỗi quá trình mới và móc các cuộc gọi API mà gây ra một cửa sổ được kích hoạt.
Phần cuối cùng là một phần dễ dàng, nhờ có các thư viện API hooking tuyệt vời ngoài kia. Tôi đã sử dụng rất tuyệt mhook library:

#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;
}

Từ các thử nghiệm của tôi trở lại sau đó, điều này đã làm việc tuyệt vời. Ngoại trừ phần tải DLL vào mọi tiến trình mới. Như người ta có thể tưởng tượng, đó là không có gì để có quá nhẹ. Tôi đã sử dụng AppInit_DLLs tiếp cận trở lại sau đó (mà chỉ đơn giản là không đủ).

Về cơ bản, điều này hoạt động rất tốt. Nhưng tôi không bao giờ tìm thấy thời gian để viết cái gì đó đúng đưa DLL của tôi vào các tiến trình mới. Và thời gian đầu tư vào điều này phần lớn làm lu mờ sự phiền toái mà việc lấy cắp trọng tâm làm tôi gây ra.

Ngoài vấn đề tiêm DLL, cũng có một phương pháp lấy cắp tiêu điểm mà tôi không đề cập trong quá trình triển khai trên Google Code. Một đồng nghiệp thực sự đã thực hiện một số nghiên cứu bổ sung và đề cập đến phương pháp đó. Vấn đề đã được thảo luận trên SO: https://stackoverflow.com/questions/7430864/windows-7-prevent-application-from-losing-focus


45
2018-03-24 09:56



Bạn có nghĩ rằng giải pháp này của bạn có thể được chuyển sang Java không? Tôi đã tìm kiếm và đặt câu hỏi nhưng không tìm thấy gì cả. Có lẽ tôi có thể nhập thư viện hook vào java bằng cách sử dụng jne? - Tomáš Zato
@ TomášZato: Không có ý tưởng. Tôi không chủ động sử dụng mã này. - Der Hochstapler
Tôi đang cố gắng để biên dịch nó như là C + + ít nhất (và sau đó tiêm / loại bỏ các DLL biên dịch từ Java). Nhưng điều đó cũng không tốt lắm. Tôi không muốn thảo luận ở đây trong các bình luận, nhưng nếu bạn thực sự có thể giúp tôi với nó để làm việc, tôi sẽ rất duyên dáng! Tôi tạo ra một phòng chat, nếu tôi nhận được rằng để làm việc tôi sẽ đăng bình luận làm thế nào để làm như vậy ở đây: chat.stackexchange.com/rooms/21637/… - Tomáš Zato


Trong Windows 7, ForegroundLockTimeout mục đăng ký không còn được kiểm tra, bạn có thể xác minh điều này bằng Process Monitor. Trong thực tế, trong Windows 7 họ không cho phép bạn thay đổi cửa sổ nền trước. Đi và đọc về chi tiết của nó, nó thậm chí đã có từ Windows 2000.

Tuy nhiên, tài liệu hút và họ đuổi theo nhau và tìm cách xung quanh.

Vì vậy, có một cái gì đó buggy đang xảy ra với SetForegroundWindowhoặc các hàm API tương tự ...

Cách duy nhất để thực sự làm điều này đúng là tạo một ứng dụng nhỏ gọi định kỳ LockSetForegroundWindow, hầu như vô hiệu hóa mọi cuộc gọi đến hàm API lỗi của chúng tôi.

Nếu đó là không đủ (một cuộc gọi API lỗi nữa?) Bạn có thể tiến xa hơn và làm một số Giám sát API để xem điều gì đang xảy ra và sau đó bạn chỉ cần móc các cuộc gọi API trên mọi quá trình sau đó bạn có thể loại bỏ bất kì các cuộc gọi gây rối lên nền trước. Tuy nhiên, trớ trêu thay, điều này không được khuyến khích bởi Microsoft ...


22
2018-03-22 09:52



Có ai có một trường hợp sử dụng tái sản xuất này trong Windows 7? Cho rằng mọi người thay vì trải nghiệm ngược lại (ví dụ, tôi thường thấy Windows đang ẩn đằng sau cửa sổ hiện tại của mình) và tôi chưa thấy điều này xảy ra trong Windows 7, nó sẽ khá khó chịu khi viết một ứng dụng nhưng không thể kiểm tra nó. Hơn nữa, khi Microsoft tuyên bố điều này sẽ không còn xảy ra với Windows 7. Tại những người tốt nhất phát hiện ra rằng nó chỉ có thể chuyển trọng tâm của bàn phím một cách tình cờ, cuộc gọi API này sẽ khắc phục điều đó nhưng tôi không biết cách kiểm tra xem nó có thực sự hoạt động hay không .. . - Tom Wijsman
Trình cài đặt (dựa trên InnoSetup) khởi chạy các quy trình khác và các thiết lập khác (ẩn), nhưng tôi không biết người tạo thiết lập nào dựa trên chúng. - Daniel Beck♦
@TomWijsman: Mở regedit, tìm kiếm một số văn bản ngẫu nhiên sẽ không được tìm thấy. Đi vào ứng dụng khác và bắt đầu nhập. Khi tìm kiếm kết thúc, regedit sẽ lấy cắp tiêu điểm. - endolith
@endolith: Không thể tái sản xuất, sử dụng Windows 8 Replase Preview ở đây. Bạn đang sử dụng hệ điều hành nào? Trong trường hợp của tôi nó chỉ làm nổi bật các ứng dụng ở phía dưới nhưng không làm gián đoạn trình duyệt của tôi ở tất cả ... - Tom Wijsman
Có, Win7 Pro 64-bit. Và việc lấy cắp tiêu điểm thậm chí còn tồi tệ hơn đối với các quy trình nâng cao, vì chúng nắm bắt được sự nhấn <Enter> của bạn khi chúng không nên, và bạn bảo nó làm cho hệ thống của bạn vô tình bị vòi. Không có gì nên không bao giờ có thể ăn cắp tập trung. - endolith


Có một tùy chọn trong TweakUI điều này. Nó ngăn chặn hầu hết các thủ thuật thông thường mà các nhà phát triển phần mềm đáng ngờ sử dụng để tập trung vào ứng dụng của họ.

Đó là một cuộc chiến vũ trang đang diễn ra, vì vậy tôi không biết liệu nó có hiệu quả với mọi thứ hay không.

Cập nhật: Theo EndangeredMassa, TweakUI không hoạt động trên Windows 7.


18
2017-08-05 09:12



tweakui có tương thích với windows 7 không? - frankster
@frankster. Không có ý kiến, xin lỗi, tôi nghi ngờ nó có lẽ không phải là. Tải xuống và dùng thử. Báo cáo lại nếu bạn làm như vậy mọi người đều biết. - Simon P Stevens
Ngay cả khi sử dụng cài đặt đăng ký mà bộ TweakUI không hoạt động trên Win7. - EndangeredMassa
@EndangeredMassa mà khóa registry là gì? - n611x007
Khóa đăng ký là HKEY_CURRENT_USER \ Control Panel \ Desktop \ ForegroundLockTimeout (tính bằng mili giây). Và có, nó không hoạt động trong Windows 7 nữa. - foo


Tôi tin rằng một số nhầm lẫn có thể tồn tại, vì có hai cách để "lấy cắp tiêu điểm": (1) một cửa sổ đến nền trước, và (2) cửa sổ nhận được tổ hợp phím.

Vấn đề được đề cập ở đây có lẽ là vấn đề thứ hai, trong đó cửa sổ tuyên bố trọng tâm bằng cách tự đưa nó vào nền trước - mà không có yêu cầu hoặc sự cho phép của người dùng.

Cuộc thảo luận phải tách ra ở đây giữa XP và 7.

Windows XP

Trong XP có một đăng ký hack mà làm cho XP làm việc giống như Windows 7 trong việc ngăn chặn các ứng dụng từ ăn cắp tập trung:

  1. Sử dụng regedit để đi đến: HKEY_CURRENT_USER\Control Panel\Desktop.
  2. Nhấp đúp vào ForegroundLockTimeout và đặt giá trị của nó theo hệ thập lục phân thành 30d40.
  3. Nhấn OK và thoát khỏi regedit.
  4. Khởi động lại PC của bạn để các thay đổi có hiệu lực.

Windows 7

(Các cuộc thảo luận dưới đây chủ yếu áp dụng cho XP là tốt.)

Hãy hiểu rằng không có cách nào trong đó Windows hoàn toàn có thể chặn các ứng dụng khỏi ăn cắp tiêu điểm và vẫn hoạt động. Ví dụ: nếu trong quá trình sao chép tệp, vi-rút của bạn đã phát hiện một mối đe dọa có thể xảy ra và muốn bật lên cửa sổ yêu cầu bạn thực hiện hành động, nếu cửa sổ này bị chặn sau đó bạn sẽ không bao giờ hiểu tại sao bản sao không bao giờ chấm dứt.

Trong Windows 7, chỉ có một sửa đổi có thể đối với hành vi của Windows, đó là sử dụng MS-Windows tập trung theo dõi chuột, trong đó tiêu điểm và / hoặc kích hoạt luôn đi đến cửa sổ bên dưới con trỏ. Một sự chậm trễ có thể được thêm vào để tránh các ứng dụng popping lên trên tất cả các máy tính để bàn.
Xem bài viết này: Windows 7 - Chuột di chuột giúp cửa sổ hoạt động - Bật.

Nếu không, người ta phải phát hiện và trung hòa chương trình tội lỗi: Nếu đây luôn là ứng dụng tương tự đang tập trung, thì ứng dụng này được lập trình để lấy tiêu điểm và ngăn chặn điều này có thể được thực hiện bằng cách vô hiệu hóa nó khỏi bắt đầu với máy tính hoặc sử dụng một số cài đặt do ứng dụng đó cung cấp để tránh hành vi này.

Bạn có thể sử dụng tập lệnh VBS bao gồm trong Mã VB xác định ai đang lấy cắp trọng tâm, tác giả dùng để xác định thủ phạm là trình cập nhật "gọi về nhà" cho phần mềm máy in.

Một biện pháp tuyệt vọng khi mọi thứ khác thất bại, và nếu bạn đã xác định được ứng dụng được lập trình kém này, là để giảm thiểu nó và hy vọng rằng sau đó sẽ không mang lại cho chính nó để phía trước. Hình thức giảm thiểu mạnh hơn là vào khay bằng cách sử dụng một trong các sản phẩm miễn phí được liệt kê trong Minimizer ứng dụng miễn phí tốt nhất.

Ý tưởng cuối cùng theo thứ tự tuyệt vọng là làm gãy máy tính để bàn của bạn hầu như bằng cách sử dụng một sản phẩm nhu la Máy tính để bàn hoặc là Dexpot, và thực hiện công việc của bạn trên một máy tính để bàn khác với mặc định.

[CHỈNH SỬA]

Khi Microsoft đã gỡ bỏ Thư viện lưu trữ, đây là đoạn mã VB được sao chép ở trên:

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

14
2018-06-09 09:22



"nếu cửa sổ này bị chặn thì bạn sẽ không bao giờ hiểu tại sao bản sao không bao giờ chấm dứt" Điều đó không đúng. Hành vi chính xác là thông báo cho người dùng bằng biểu tượng thanh tác vụ nhấp nháy (hoặc có thể là thông báo bật lên hoặc thông báo trên máy nướng bánh mì hoặc thứ gì đó). Gián đoạn người dùng với một cửa sổ chặn các tổ hợp phím của họ có nghĩa là họ nói với phần mềm chống vi-rút để thực hiện một hành động này hay cách khác một cách ngẫu nhiên. Chắc chắn không phải là cách tốt để làm mọi thứ. - endolith
"nếu cửa sổ này bị chặn thì bạn sẽ không bao giờ hiểu tại sao bản sao không bao giờ chấm dứt" Điều đó không đúng. Hành vi đúng là thông báo cho người dùng bằng biểu tượng thanh tác vụ nhấp nháy ...   Đã có lần tôi nhấp vào một nút hoặc một cái gì đó trong một chương trình đang chạy gây ra một hộp thoại phương thức mới được tạo (ví dụ: mở tập tin), nhưng sau đó tôi chuyển sang chương trình khác trước khi hộp thoại được tạo. Do đó, hộp thoại bị ẩn và không thể chuyển sang chương trình khác và hộp thoại không thể bị loại bỏ. Không phải nút tác vụ cũng không Alt-Tab công trinh; chỉ buộc hộp thoại ở phía trước. - Synetech
@Synetech: Đôi khi giải pháp duy nhất cho hộp thoại không phải là phía trước là để giết nhiệm vụ. Các thuật toán tập trung trong Windows thực sự tệ hại. - harrymc
@harrymc, tôi không bao giờ phải nghỉ mát để giết một trong những ứng dụng. Tôi chỉ chạy chương trình thao tác cửa sổ của tôi (WinSpy ++ thủ thuật chỉ tuyệt vời) và ẩn cửa sổ ở phía trước, sau đó tôi có thể bỏ qua hộp thoại bị kẹt lại, sau đó hiển thị lại cửa sổ ẩn. Nó không thuận tiện, nhưng tốt hơn là giết chết một trong hai quá trình. - Synetech
@harrymc, không thực sự; giết chết một ứng dụng và mất công cụ chỉ làm cho hơi nước hơn, và nếu nó là một hộp thoại phương thức (mà khóa cửa sổ cha mẹ và không có nút thanh tác vụ), sau đó nó sẽ không xuất hiện trong Alt+Tab danh sách, và, theo kinh nghiệm của tôi, một cửa sổ có một hộp thoại phương thức mở không luôn luôn (không bao giờ?) hiển thị hộp thoại phương thức với Alt+Tab, đặc biệt nếu hộp thoại không bao giờ có thay đổi để lấy nét. :-| - Synetech


Ghacks có một giải pháp có thể có:

Nó xảy ra vài lần trong ngày   một số ứng dụng đánh cắp trọng tâm của   cửa sổ đang hoạt động bằng cách bật lên. Điều này   có thể xảy ra vì một số lý do,   khi tôi trích xuất tệp hoặc chuyển   kết thúc ví dụ. Nó không   vấn đề phần lớn thời gian khi điều này   xảy ra nhưng đôi khi tôi viết   và nó không chỉ có nghĩa là   Tôi phải gõ lại một số từ nhưng   tôi cũng mất tập trung và   phải bấm để lấy lại tiêu điểm.

Các Người đánh giá chuyên nghiệp trang web có mẹo   làm thế nào để ngăn chặn điều này xảy ra.   Cách dễ nhất để ngăn tiêu điểm   ăn cắp là sử dụng Tweak UI có   một cài đặt được gọi là "Ngăn chặn   ứng dụng lấy cắp tập trung ”.   Chọn tùy chọn này sẽ ngăn chặn điều đó   các ứng dụng khác bật lên đột ngột và   ăn cắp trọng tâm của cửa sổ bạn đang   hiện đang làm việc.

Điều này chỉ hoạt động khi ứng dụng   đã được giảm thiểu trước đó. Thay vì   ăn cắp tập trung nó sẽ nhấp nháy   số lần có thể xác định   trong cùng một menu trong Tweak UI. nếu bạn   không muốn sử dụng Tweak UI bạn có thể   thay đổi cài đặt trong Windows   Đăng ký.

Điều hướng đến khóa Registry   HKEY_CURRENT_USER> Bảng điều khiển>   Máy tính để bàn và thay đổi   Giá trị ForegroundLockTimeout đến 30d40   (Hệ thập lục phân) hoặc 200000 (Thập phân). Các   khóa ForeGroundFlashCount định nghĩa   lượng nhấp nháy của cửa sổ để cảnh báo   người dùng trong đó 0 có nghĩa là không giới hạn.


2
2017-08-05 09:13



Điều này không hoạt động trên bất kỳ hệ điều hành nào sau XP. Giá trị đăng ký đó đã được đặt thành giá trị đó (theo mặc định, tôi tin) và không hoạt động. - EndangeredMassa
Chỉ cần để thứ hai mà tôi đang trên Windows 7 (64-bit), trải qua tập trung ăn cắp (VS 2012 khi cuối cùng hoạt động, ví dụ f'r), và đề nghị đăng ký ở trên đã được tại chỗ. Xác nhận kỹ thuật trong câu trả lời này: superuser.com/a/403554/972 - Michael Paulukonis