44using System ;
55using System . Diagnostics ;
66using System . IO ;
7+ using System . Linq ;
78using System . Runtime . InteropServices ;
89using System . Text ;
910using 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}
0 commit comments