C# WPF申请获批';t使用Application.Run()打开;

C# WPF申请获批';t使用Application.Run()打开;,c#,wpf,C#,Wpf,我引用了System.Windows.Forms.dll,想使用Application.Run()但我的应用程序无法打开。我在控制台中没有收到任何错误,并且应用程序在任务管理器中可见 这是我的代码: public partial class MainWindow : Window { TextBoxOutputter outputter; public MainWindow() { InitializeComponent(); Init(

我引用了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':'对垃圾进行了回调 类型的已收集委托 '击键API!Keystroke.API.User32+LowLevelHook::Invoke'。今年五月 导致应用程序崩溃、损坏和数据丢失。路过时 委托给非托管代码时,托管 应用程序,直到保证永远不会调用它们为止。”


我正在使用这个API:

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

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);}
,该委托已被销毁。

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

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

显示应用程序的入口点以及创建
主窗口的位置,您可能正在做一些奇怪的事情,可能会调用Run两次或其他什么,但这并不能准确解释错误……它位于
public分部类MainWindow:Window的顶部{
为什么要调用应用程序。从窗口中运行?显示应用程序的入口点以及创建
MainWindow的位置
,看起来您可能做了一些奇怪的事情,可能调用Run两次或几次,但这并不能准确解释错误…它位于
公共部分类MainW的顶部indow:Window{
为什么调用应用程序。从窗口中运行?