WPF 应用程序无法使用 Application.Run() 打开;



我已经引用了System.Windows.Forms.dll,并且想使用Application.Run();但我的应用程序无法打开。我在控制台中没有收到任何错误,并且该应用程序在任务管理器中可见。

这是我的代码:

public partial class MainWindow : Window
{
TextBoxOutputter outputter;
public MainWindow()
{
InitializeComponent();
Init();
}
public void Init()
{
outputter = new TextBoxOutputter(TestBox);
Console.SetOut(outputter);

using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => { Console.Write(character); });
Application.Run();
}
}
}

如果没有Application.Run();应用程序会运行,但在按下任何键后立即崩溃。当它崩溃时,我收到此消息:

CallbackOnCollectedDelegate' : '对垃圾进行了回调 收集的委托类型 '击键!Keystroke.API.User32+LowLevelHook::Invoke'.这可能会 导致应用程序崩溃、损坏和数据丢失。通过时 委托给非托管代码,它们必须由托管代码保持活动状态 申请,直到保证他们永远不会被召唤。

我正在使用这个 API:https://github.com/fabriciorissetto/KeystrokeAPI

WPF 应用程序(我假设是您的(将从应用程序的入口点调用Application.Run();。您应该能够在运行应用程序之前在应用程序中设置挂钩,然后在加载 Window 时设置控制台输出。

App.xaml; 删除 StartupUri 标记并将其替换为 Startup,从而在App.xaml.cs中创建新的事件回调。

App.xaml.cs在新的启动事件回调中,您可以设置钩子。

using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => { Console.Write(character); });
Application.Run();
}

MainWindow.cs然后,一旦窗口加载完毕,您应该能够控制台的输出。

public void Init()
{
outputter = new TextBoxOutputter(TestBox);
Console.SetOut(outputter);
}

这意味着您不会在钩子仍然制作时调用Application.Run();两次。

目前,我认为问题是,您启动应用程序,该应用程序会自动初始化新实例并运行它。然后,您还调用Application.Run();它现在覆盖以前的初始化并重新开始。这意味着您的窗口、控制台和委托现在位于以前的被覆盖的实例中,并被 GC 销毁。因此,您已将击键 API 绑定到已销毁的委托 -(character) => { Console.Write(character); }

相关内容

最新更新