Skip to content

Commit 2c2596d

Browse files
committed
Fix sparse sample to use AUMID activation for package identity
1 parent e41d390 commit 2c2596d

3 files changed

Lines changed: 87 additions & 15 deletions

File tree

Samples/MultiHeadedPackage/cs/cs-wpf-sparse/PrimaryApp/MainWindow.xaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
<Button x:Name="UnregisterButton" Content="Unregister Package"
2424
Click="UnregisterButton_Click" Margin="0,0,10,0" Padding="10,5" />
2525
<Button x:Name="RestartButton" Content="Restart"
26-
Click="RestartButton_Click" Padding="10,5" />
26+
Click="RestartButton_Click" Margin="0,0,10,0" Padding="10,5" />
27+
<Button x:Name="LaunchSecondaryButton" Content="Launch Secondary App"
28+
Click="LaunchSecondaryButton_Click" Padding="10,5" />
2729
</StackPanel>
2830

2931
<TextBlock Text="Output:" FontWeight="Bold" Margin="0,10,0,5" />

Samples/MultiHeadedPackage/cs/cs-wpf-sparse/PrimaryApp/MainWindow.xaml.cs

Lines changed: 83 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Diagnostics;
66
using System.IO;
7+
using System.Linq;
78
using System.Runtime.InteropServices;
89
using System.Text;
910
using System.Windows;
@@ -16,6 +17,8 @@ public partial class MainWindow : Window
1617
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
1718
private static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName);
1819

20+
private const string PackageName = "MultiHeadedSparseSample";
21+
1922
public MainWindow()
2023
{
2124
InitializeComponent();
@@ -57,9 +60,19 @@ private async void RegisterButton_Click(object sender, RoutedEventArgs e)
5760
return;
5861
}
5962

63+
var packageManager = new PackageManager();
64+
65+
// Check if already registered
66+
var existing = packageManager.FindPackagesForUser(string.Empty)
67+
.FirstOrDefault(p => p.Id.Name == PackageName);
68+
if (existing != null)
69+
{
70+
AppendOutput("Package is already registered.");
71+
return;
72+
}
73+
6074
AppendOutput($"Registering sparse package: {msixPath}");
6175

62-
var packageManager = new PackageManager();
6376
var packageUri = new Uri(msixPath);
6477
var options = new AddPackageOptions
6578
{
@@ -81,23 +94,18 @@ private async void UnregisterButton_Click(object sender, RoutedEventArgs e)
8194
{
8295
try
8396
{
84-
int length = 0;
85-
GetCurrentPackageFullName(ref length, null);
86-
var sb = new StringBuilder(length);
87-
int result = GetCurrentPackageFullName(ref length, sb);
97+
var packageManager = new PackageManager();
98+
var package = packageManager.FindPackagesForUser(string.Empty)
99+
.FirstOrDefault(p => p.Id.Name == PackageName);
88100

89-
if (result == 15700) // APPMODEL_ERROR_NO_PACKAGE
101+
if (package == null)
90102
{
91103
AppendOutput("No package is currently registered.");
92104
return;
93105
}
94106

95-
string packageFullName = sb.ToString();
96-
AppendOutput($"Unregistering package: {packageFullName}");
97-
98-
var packageManager = new PackageManager();
99-
await packageManager.RemovePackageAsync(packageFullName);
100-
107+
AppendOutput($"Unregistering package: {package.Id.FullName}");
108+
await packageManager.RemovePackageAsync(package.Id.FullName);
101109
AppendOutput("Package unregistered successfully!");
102110
AppendOutput("Click 'Restart' to relaunch without package identity.");
103111
}
@@ -109,15 +117,76 @@ private async void UnregisterButton_Click(object sender, RoutedEventArgs e)
109117

110118
private void RestartButton_Click(object sender, RoutedEventArgs e)
111119
{
112-
var exePath = Process.GetCurrentProcess().MainModule.FileName;
113-
Process.Start(exePath);
120+
// Check if the sparse package is registered
121+
var packageManager = new PackageManager();
122+
var package = packageManager.FindPackagesForUser(string.Empty)
123+
.FirstOrDefault(p => p.Id.Name == PackageName);
124+
125+
if (package != null)
126+
{
127+
// Launch through the package activation manager so the process gets identity
128+
string aumid = $"{package.Id.FamilyName}!App";
129+
AppendOutput($"Activating with AUMID: {aumid}");
130+
ActivateByAumid(aumid);
131+
}
132+
else
133+
{
134+
// No package registered, just relaunch the exe directly
135+
var exePath = Process.GetCurrentProcess().MainModule.FileName;
136+
Process.Start(exePath);
137+
}
138+
114139
Application.Current.Shutdown();
115140
}
116141

142+
private void LaunchSecondaryButton_Click(object sender, RoutedEventArgs e)
143+
{
144+
var packageManager = new PackageManager();
145+
var package = packageManager.FindPackagesForUser(string.Empty)
146+
.FirstOrDefault(p => p.Id.Name == PackageName);
147+
148+
if (package != null)
149+
{
150+
string aumid = $"{package.Id.FamilyName}!SecondaryApp";
151+
AppendOutput($"Launching secondary app with AUMID: {aumid}");
152+
ActivateByAumid(aumid);
153+
}
154+
else
155+
{
156+
AppendOutput("Package not registered. Register the package first.");
157+
}
158+
}
159+
160+
private static void ActivateByAumid(string aumid)
161+
{
162+
var clsid = new Guid("45ba127d-10a8-46ea-8ab7-56ea9078943c");
163+
var iid = new Guid("2e941141-7f97-4756-ba1d-9decde894a3d");
164+
165+
uint hr = CoCreateInstance(ref clsid, IntPtr.Zero, 0x4 /* CLSCTX_LOCAL_SERVER */, ref iid, out object obj);
166+
if (hr != 0)
167+
throw new COMException("Failed to create ApplicationActivationManager", (int)hr);
168+
169+
var aam = (IApplicationActivationManager)obj;
170+
aam.ActivateApplication(aumid, string.Empty, 0, out _);
171+
}
172+
117173
private void AppendOutput(string message)
118174
{
119175
OutputTextBox.Text += message + Environment.NewLine;
120176
OutputTextBox.ScrollToEnd();
121177
}
178+
179+
[DllImport("ole32.dll")]
180+
private static extern uint CoCreateInstance(
181+
ref Guid rclsid, IntPtr pUnkOuter, uint dwClsContext,
182+
ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
183+
184+
[ComImport, Guid("2e941141-7f97-4756-ba1d-9decde894a3d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
185+
private interface IApplicationActivationManager
186+
{
187+
IntPtr ActivateApplication([In] string appUserModelId, [In] string arguments, [In] uint options, [Out] out uint processId);
188+
IntPtr ActivateForFile([In] string appUserModelId, [In] IntPtr itemArray, [In] string verb, [Out] out uint processId);
189+
IntPtr ActivateForProtocol([In] string appUserModelId, [In] IntPtr itemArray, [Out] out uint processId);
190+
}
122191
}
123192
}

Samples/MultiHeadedPackage/cs/cs-wpf-sparse/PrimaryApp/Package.appxmanifest

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<DisplayName>Multi-Headed Sparse Sample</DisplayName>
1717
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
1818
<Logo>Assets\logo.png</Logo>
19+
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
1920
</Properties>
2021

2122
<Dependencies>

0 commit comments

Comments
 (0)