提问人:Alex Netkachov 提问时间:11/12/2023 更新时间:11/12/2023 访问量:39
WPF 应用第一次加载带有窗口的插件,但第二次无法显示窗口
WPF app loads a plugin with a window well first time, but fails to show the window second time
问:
该应用通过加载程序集来实现插件。插件可以多次加载,而且工作非常简单,直到我从插件中显示一个窗口。它第一次工作,但第二次不会打开窗口。
例
主机应用
Host.csproj(主机.csproj)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<LangVersion>default</LangVersion>
<TargetFramework>net48</TargetFramework>
<OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF>
<StartupObject>Host.MainModule</StartupObject>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<ApplicationDefinition Include="MainModule.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
</ItemGroup>
</Project>
MainModule.xaml
<Application x:Class="Host.MainModule"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"/>
MainModule.xaml.cs
using System;
using System.IO;
using System.Reflection;
using System.Windows;
namespace Host;
public partial class MainModule
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
LoadAndRun(@"..\..\..\..\..\Service\bin\x64\Debug\net48\Service.dll");
LoadAndRun(@"..\..\..\..\..\Service\bin\x64\Debug\net48\Service.dll");
MessageBox.Show("ok");
Shutdown();
}
private static void LoadAndRun(string path) {
var folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var assembly = Assembly.LoadFile(Path.GetFullPath(Path.Combine(folder, path)));
var provider = assembly.GetType("Service.Provider");
var instance = Activator.CreateInstance(provider);
var method = provider.GetMethod("Run");
method.Invoke(instance, null);
}
}
服务库
服务.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<LangVersion>default</LangVersion>
<TargetFramework>net48</TargetFramework>
<OutputType>library</OutputType>
<UseWPF>true</UseWPF>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
</Project>
提供程序.cs
using System;
using System.Diagnostics;
using Microsoft.SqlServer.Server;
namespace Service;
public sealed class Provider {
public void Run() {
var form = new Form();
var sw = Stopwatch.StartNew();
form.ShowDialog();
Console.WriteLine($"{nameof(Provider)}.{nameof(Run)}: form was opened for {sw.ElapsedMilliseconds} ms");
}
}
Form.xaml
<Window x:Class="Service.Form"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Form"
Height="400" Width="200">
</Window>
Form.xaml.cs
using System;
namespace Service;
public partial class Form {
public Form() {
Console.WriteLine($"{nameof(Form)}.{nameof(Form)}: start");
InitializeComponent();
Console.WriteLine($"{nameof(Form)}.{nameof(Form)}: done");
}
}
跑
启动后,应用会显示一次表单,然后显示一个消息框。
控制台输出为:
Form.Form: start
Form.Form: done
Provider.Run: form was opened for 1159 ms
Form.Form: start
Form.Form: done
Provider.Run: form was opened for 0 ms
如您所见,表单第二次启动,没有例外,但会立即关闭。
我将感谢您在这件事上的帮助。谢谢!
答:
0赞
emoacht
11/12/2023
#1
检查 Application.ShutdownMode。默认值为 OnLastWindowClose,因此应用程序将在第一个窗口关闭时关闭。如果要使应用程序保持运行,请将其更改为 OnExplicitShutdown。
它与从单独的程序集加载 Window 无关。
评论