gpt4 book ai didi

c# - 消息循环正在阻塞应用程序

转载 作者:太空宇宙 更新时间:2023-11-03 16:01:03 29 4
gpt4 key购买 nike

我需要关闭网络浏览器控件中的下载弹出窗口(禁止用户下载文件)。我怎样才能做到这一点?

我发现了这个: How to block downloads in .NET WebBrowser control?

我使用了第二个答案。它正在工作,但我有问题。似乎调用创建对象的 GetText 阻塞了整个线程。我没有任何解决方案。

private static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
if (idObject == 0 && idChild == 0)
{
if(eventType == EVENT_OBJECT_CREATE)
{
string text = GetText(hwnd);
if (text.Contains("File Download"))
SendMessage(hwnd, 0x0010, IntPtr.Zero, IntPtr.Zero); //close window
}
}
}

public static string GetText(IntPtr hWnd)
{
int length = GetWindowTextLength(hWnd); //my app is freezing here - i think it's because i'm calling it from message loop.
StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}

//编辑

好的,感谢@sgorozco 的建议。现在我正在使用 SetWindowsHookEx 和 WH_CBT。然后在消息循环中我正在捕获 HCBT_CREATEWND 事件。但是我在从 lparm 获取 CBT_CREATEWND 时遇到了问题。我收到“Managed Debugging Assistant 'FatalExecutionEngineError'”异常。

这是我当前的代码:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CREATESTRUCT
{
public IntPtr lpCreateParams;
public IntPtr hInstance;
public IntPtr hMenu;
public IntPtr hwndParent;
public int cy;
public int cx;
public int y;
public int x;
public int style;
public string lpszName;
public string lpszClass;
public int dwExStyle;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CBT_CREATEWND
{
public IntPtr lpcs;
public IntPtr hwndInsertAfter;

}

private static IntPtr MessageLoopFuctnion(int code, IntPtr wParam, IntPtr lParam)
{
if (code < 0)
{
return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}

if(code == 3)
{
CBT_CREATEWND info;
info = (CBT_CREATEWND)Marshal.PtrToStructure(lParam, typeof(CBT_CREATEWND));

CREATESTRUCT info1;
info1 = (CREATESTRUCT)Marshal.PtrToStructure(info.lpcs, typeof(CREATESTRUCT)); //here exception is throwing

if (info1.lpszName != null && info1.lpszName.Contains("File Download")))
SendMessage(wParam, 0x0010, IntPtr.Zero, IntPtr.Zero); //close popup

//Marshal.FreeHGlobal(info.lpcs); //error, why?
//Marshal.FreeHGlobal((IntPtr)lParam.ToUInt64());
}


return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}

//set hook
IntPtr hWinEventHook = SetWindowsHookEx(5, myCallbackDelegate, user32DLL, 0);

//编辑2

这是我的定义:

 private delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam);
private static HookProc myCallbackDelegate = new HookProc(MessageLoopFuctnion);

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetWindowsHookEx(int hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

我的 myCallbackDelegate 是一个静态字段,所以它肯定不是 GC 收集的。临时我每 500 毫秒枚举所有窗口并查找包含文本“文件下载”的对话框。但这是一个丑陋的解决方案。

最佳答案

FatalExecutionEngineError 的原因是 CREATESTRUCT 中的字符串。将它们替换为 IntPtr,您将不会有任何异常。

[StructLayout(LayoutKind.Sequential)]
public struct CREATESTRUCT {
public IntPtr lpCreateParams;
public IntPtr hInstance;
public IntPtr hMenu;
public IntPtr hwndParent;
public int cy;
public int cx;
public int y;
public int x;
public int style;
public IntPtr lpszName;
public IntPtr lpszClass;
public int dwExStyle;
}

(也许您可以使用 GetClassName 和 GetWindowText 作为解决方法。未测试)

关于c# - 消息循环正在阻塞应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21392465/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com