c# - 检测 OpenFileDialog

标签 c# windows winapi hook

对于 DLP 软件的一个非常特殊的要求,我正在尝试检测 OpenFileDialogs 并在捕获所选文件后取消文件选择操作。

我该怎么做?

我在鼠标和键盘上放置了一个全局钩子(Hook)。我检测到用户可以执行以在 OpenFileDialog 窗口中选择文件的所有操作。

直到现在我无法做的是通过 hwnd 检测窗口是否是 OpenFileDialog。

我为什么要这样尝试?

我是一名高级程序员,最初尝试使用 Windows Hook ,但没有成功。我尝试使用 easyhook 和 deviare2。在 COM (IFileDialog) 组件调用中放置全局 Hook 似乎没有更简单的方法。

有没有办法通过 hwnd 检测一个窗口是否是默认的 Windows OpenFileDialog 窗口?

public bool IsOpenFileDialog(IntPtr hwnd)
{
    return ?
}

最佳答案

作为部分解决方案(对手可以模仿这样的对话),我建议检查窗口是否是标准对话,如果是,它是否有标题中的“保存”(您可以在此处放置一个更好的 criterium):

首先,让我们检查:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx

 using System.Runtime.InteropServices;

 ... 

 [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  private static extern int GetClassName(IntPtr hWnd, 
    StringBuilder lpClassName, 
    int nMaxCount);

  private static String WndClassName(IntPtr handle) {
    int length = 1024;

    StringBuilder sb = new StringBuilder(length);

    GetClassName(handle, sb, length);

    return sb.ToString();
  }

  public static bool IsDialogClassName(IntPtr handle) {
    // Standard windows dialogs like OpenFileDialog, SaveFileDialog have #32770 class name 
    return "#32770".Equals(WndClassName(handle));
  } 

但是,它的标准太宽泛了:Save File DialogOpen File Dialog 都通过了它。让我们检查窗口的标题:

  [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
   private static extern int GetWindowTextLength(IntPtr hWnd);

  [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
   static extern int GetWindowText(IntPtr hWnd, 
     StringBuilder text, 
     int length);

   private static String WindowText(IntPtr handle) {
     int length = GetWindowTextLength(handle);

     StringBuilder sb = new StringBuilder(length + 1);

     GetWindowText(handle, sb, length + 1);

     return sb.ToString();
   }

   public static bool IsSaveCaption(IntPtr handle) {
     //TODO: put a better check for dialog's caption here
     return WindowText(handle).IndexOf("Save", StringComparison.OrdinalIgnoreCase) >= 0;
   } 

最后:

  public bool IsOpenFileDialog(IntPtr hwnd) {
    return IsDialogClassName(hwnd) && 
           !IsSaveCaption(hwnd);
  }

当然你可能想要一些其他的标准,但我希望这两个就足够了

关于c# - 检测 OpenFileDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44907938/

相关文章:

c# - 在运行时创建具有通用接口(interface)的通用类型

windows - 如何从提升的 PowerShell 控制台以非管理员身份运行进程?

windows - Windows 批处理文件中的三重 IF 语句?如果如果如果如果?其他错误

c++ - atexit() 处理程序中的 Windows 获取由::exit() 设置的当前进程退出代码

c++ - 如何找到我的线程在哪个 CPU 内核上运行

c++ - 检测 Windows 在崩溃或电源故障后何时重新启动

c# - C#翻转位图函数

c# - 包装器是测试静态依赖项的唯一方法吗?

c# - 哪种方法最适合使用 Rest API 的 GET、POST

c++ - HANDLE 指向的结构