英文:
How to launch a UWP app via a button in WPF
问题
以下是您要翻译的部分:
如果我直接在Visual Studio中启动我的UWP应用程序(WLAN连接器),它可以正常工作。但是,如果我尝试在WPF程序中启动它,它会以正确的大小打开UWP窗口,但只显示标准的启动屏幕,不会启动程序?我不知道出了什么问题?
NuGet包已安装:
NUGET Microsoft.Toolkit.Wpf.UI.XamlHost
NUGET Microsoft.Windows.SDK.Contracts
.NET 4.8
希望有人对UWP有更多经验。谢谢。
下面是整个项目,一个WPF启动程序和一个无法从WPF应用程序中正确启动的UWP应用程序,也许有人可以帮助我解决这个问题:
UWP应用程序(WLAN连接器)
App.xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
...
// 以下省略
MainPage.xaml:
<Page
x:Class="WLANConnectorUWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WLANConnectorUWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Width="300" Height="200">
...
</Page>
MainPage.xaml.cs
using System;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Devices.Enumeration;
using Windows.Devices.WiFi;
...
// 以下省略
WPF启动程序:
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
...
// 以下省略
MainWindow.xaml
<Window x:Class="UWPStartTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xamlhost="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
</Window>
希望这能帮助您解决问题。
英文:
If i start my UWP App (WLAN Connector) directly in Visual Studio, it works fine. But, if i try to start it in a WPF Program, it will open the UWP Window with the correct size, but it shows only the standard splashscreen and it will not start the program? I have no idea what is wrong?
The Nuget Pcage is installed:
NUGET Microsoft.Toolkit.Wpf.UI.XamlHost
NUGET Microsoft.Windows.SDK.Contracts
.NET 4.8
Hope somebody has a little bit more experience with UWP than me.
Thanks
Below you will find the hole project, a WPF Start Program and the UWP App that will not start correct from the WPF App, maybe someone could help me with it:
UWP App (WLAN Connector)
App.xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.ApplicationModel.Core;
namespace WLANConnectorUWP
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.SizeChanged += RootFrame_SizeChanged;
Window.Current.Content = rootFrame;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
ApplicationView.PreferredLaunchViewSize = new Size(300, 300);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
var view = ApplicationView.GetForCurrentView();
var titleBar = view.TitleBar;
if (titleBar != null)
{
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
titleBar.ButtonForegroundColor = Colors.Transparent;
titleBar.ButtonInactiveForegroundColor = Colors.Transparent;
titleBar.BackgroundColor = Colors.Transparent;
titleBar.ForegroundColor = Colors.Transparent;
titleBar.InactiveBackgroundColor = Colors.Transparent;
titleBar.InactiveForegroundColor = Colors.Transparent;
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
}
Window.Current.Activate();
}
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}
private void RootFrame_SizeChanged(object sender, SizeChangedEventArgs e)
{
ApplicationView.GetForCurrentView().TryResizeView(new Size(300, 300));
}
}
}
MainPage.xaml:
<Page
x:Class="WLANConnectorUWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WLANConnectorUWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Width="300" Height="200">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<ComboBox x:Name="AvailableNetworksComboBox" Width="200" Header="WLAN-Netzwerke"/>
<TextBox x:Name="PasswordTextBox" Width="200" Header="Passwort" Margin="0,10,0,0"/>
<Button x:Name="ConnectButton" Width="200" Content="Verbinden" Margin="0,10,0,0" Click="ConnectButton_Click"/>
</StackPanel>
</Page>
MainPage.xaml.cs
using System;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Devices.Enumeration;
using Windows.Devices.WiFi;
using Windows.Security.Credentials;
using Windows.UI.Popups;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace WLANConnectorUWP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
private WiFiAdapter _wifiAdapter;
public MainPage()
{
InitializeComponent();
InitializeWiFiAdapter();
}
private async void InitializeWiFiAdapter()
{
var access = await WiFiAdapter.RequestAccessAsync();
if (access != WiFiAccessStatus.Allowed)
{
await new MessageDialog("Zugriff auf WLAN-Adapter nicht erlaubt").ShowAsync();
return;
}
var result = await DeviceInformation.FindAllAsync(WiFiAdapter.GetDeviceSelector());
if (result.Count == 0)
{
await new MessageDialog("Kein WLAN-Adapter gefunden").ShowAsync();
return;
}
_wifiAdapter = await WiFiAdapter.FromIdAsync(result.First().Id);
await _wifiAdapter.ScanAsync();
foreach (var network in _wifiAdapter.NetworkReport.AvailableNetworks)
{
AvailableNetworksComboBox.Items.Add(network.Ssid);
}
}
private async void ConnectButton_Click(object sender, RoutedEventArgs e)
{
var selectedSsid = AvailableNetworksComboBox.SelectedItem as string;
if (selectedSsid == null)
{
await new MessageDialog("Bitte wählen Sie ein WLAN-Netzwerk aus der Liste aus").ShowAsync();
return;
}
var selectedNetwork = _wifiAdapter.NetworkReport.AvailableNetworks.FirstOrDefault(network => network.Ssid == selectedSsid);
if (selectedNetwork == null)
{
await new MessageDialog("Das ausgewählte Netzwerk wurde nicht gefunden").ShowAsync();
return;
}
string password = PasswordTextBox.Text;
WiFiReconnectionKind reconnectionKind = WiFiReconnectionKind.Automatic;
var credential = new PasswordCredential { Password = password };
var connectionResult = await _wifiAdapter.ConnectAsync(selectedNetwork, reconnectionKind, credential);
if (connectionResult.ConnectionStatus == WiFiConnectionStatus.Success)
{
await new MessageDialog("Erfolgreich mit dem Netzwerk verbunden").ShowAsync();
}
else
{
await new MessageDialog($"Verbindungsfehler: {connectionResult.ConnectionStatus}").ShowAsync();
}
}
}
}
WPF Start Program:
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
namespace UWPStartTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Process.Start("myapp://");
}
}
}
//NUGET Microsoft.Toolkit.Wpf.UI.XamlHost wird benltigt!!!
//NUGET Microsoft.Windows.SDK.Contracts für die passende WIN 10 Version
//.NET 4.8 oder höher
MainWindow.xaml
<Window x:Class="UWPStartTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xamlhost="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
</Window>
答案1
得分: 1
你可以使用协议在WPF中启动UWP。
- 在你的UWP项目的
Package.appxmanifest
文件中定义协议名称。
<Extensions>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="uwptestapp">
<uap:DisplayName>UWP-Test-app</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
- 在App.xaml.cs中重写
Application.OnActivated
方法。
protected override void OnActivated(IActivatedEventArgs args)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
rootFrame.Navigate(typeof(MainPage));
Window.Current.Activate();
}
- 使用
LaunchUriAsync
与协议名称启动UWP在WPF中。
using Windows.System;
private async void Button_Click(object sender, RoutedEventArgs e)
{
var res = await Launcher.LaunchUriAsync(new Uri("uwptestapp:"));
}
注意:要在桌面应用程序中调用Windows Runtime API,需要修改目标框架。
右键单击你的WPF项目 -> 选择“卸载项目” -> 修改TargetFramework
。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows10.0.22621.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<SupportedOSPlatformVersion>10.0.22621.0</SupportedOSPlatformVersion>
</PropertyGroup>
</Project>
英文:
You can launch UWP in WPF with Protocol.
- Define Protocol Name in file
Package.appxmanifest
in your UWP project.
> <Extensions>
> <uap:Extension Category="windows.protocol">
> <uap:Protocol Name="uwptestapp">
> <uap:DisplayName>UWP-Test-app</uap:DisplayName>
> </uap:Protocol>
> </uap:Extension>
> </Extensions>
- Override Application.OnActivated in the App.xaml.cs.
> protected override void OnActivated(IActivatedEventArgs args)
> {
> Frame rootFrame = Window.Current.Content as Frame;
> if (rootFrame == null)
> {
> rootFrame = new Frame();
> Window.Current.Content = rootFrame;
> }
>
> rootFrame.Navigate(typeof(MainPage));
> Window.Current.Activate();
> }
- Use
LaunchUriAsync
with Protocol Name to launch UWP in WPF.
> using Windows.System;
>
> private async void Button_Click(object sender, RoutedEventArgs e)
> {
> var res=await Launcher.LaunchUriAsync(new Uri("uwptestapp:"));
> }
Note: To call Windows Runtime APIs in desktop apps, you need to modify target Framework.
Right click your WPF project -> Select Unload Project
-> Modify TargetFramework
.
> <Project Sdk="Microsoft.NET.Sdk">
>
> <PropertyGroup>
> <OutputType>WinExe</OutputType>
> <TargetFramework>net6.0-windows10.0.22621.0</TargetFramework>
> <Nullable>enable</Nullable>
> <UseWPF>true</UseWPF>
> <SupportedOSPlatformVersion>10.0.22621.0</SupportedOSPlatformVersion>
> </PropertyGroup>
>
> </Project>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论