I have a solution consisting of a Windows Application Packaging Project that groups two other projects:
- A UWP project, named UwpUI, which is the entry point of the package. It can also be launched by protocol activation.
- A .NET framework project, named FrameworkLogic, declared as Fulltrust.
An AppServiceConnection connects the two projects and allows a bi-directional communication between them. It works using a well known pattern, described in this blog post by Stefan Wick: Uwp with desktop extension-part 3
The package.appxmanifest (of my app) contains this.
<Extensions>
<desktop:Extension
Category="windows.fullTrustProcess"
Executable="FrameworkLogic\FrameworkLogic.exe">
</desktop:Extension>
<uap:Extension Category="windows.appService">
<uap:AppService Name="BidirectionalCom" />
</uap:Extension>
<uap:Extension Category="windows.protocol" Executable="UwpUI.exe"
EntryPoint="UwpUI.App">
<uap:Protocol Name="protoLaunch" />
</uap:Extension>
The uwp starts the fulltrust process like that:
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
In the entrypoint of the fulltrust .net framework, the connection is made with:
Connection = new AppServiceConnection();
Connection.AppServiceName = "BidirectionalCom";
var familyName = Package.Current.Id.FamilyName;
Connection.PackageFamilyName = familyName;
Connection.RequestReceived += Connection_RequestReceived;
Connection.ServiceClosed += Connection_ServiceClosed;
AppServiceConnectionStatus status = await Connection.OpenAsync();
opening the connection result in a call on the uwp side in the method
OnBackgroundActivated(BackgroundActivatedEventArgs args)
Where a reference to the connection is kept. Everything works.
The new requirement is this : set a console app (or a WPF app) as the package entry point.
If the package is launched without arguments, the new console app launches the uwp project by protocol activation. The bi-directional communication between the UWP and the .NET framework is instantiated and used.
If the app is launched with arguments (in my case, from the jumplist), then only the console app is used.
Adding the new project and setting it as the package entry point results in the following error: DEP0700: Registration of the app failed. [0x80073CF6] AppxManifest.xml(44,10): error 0x80080204: Cannot register the package because the extension is missing an EntryPoint or StartPage attribute.
The solution on this SO post got me further. Seems logical : the appservice must be defined under the project that uses it, which is not the package's entrypoint anymore. My package manifest now include a second app (UwpUI) and looks like this:
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
<uap:VisualElements DisplayName="Home" Description="Package" BackgroundColor="white" Square44x44Logo="Images\Square44x44Logo.png">
</uap:VisualElements>
<Extensions>
<uap:Extension Category="windows.protocol" Executable="UwpUI.exe" EntryPoint="UwpUI.App" ><uap:Protocol Name="protoLaunch" />
</uap:Extension>
<desktop:Extension Category="windows.fullTrustProcess" Executable="FrameworkLogic\FrameworkLogic.exe">
</desktop:Extension>
</Extensions>
</Application>
<Application Id="App2" Executable="UwpUI.exe" EntryPoint="UwpUI.App">
<uap:VisualElements AppListEntry="none" DisplayName="Home" Description="Package" BackgroundColor="white" Square44x44Logo="Images\Square44x44Logo.png" Square150x150Logo="Images\Square150x150Logo.png">
<uap:DefaultTile ShortName="-TestApp-" Square71x71Logo="Images\SmallTile.png" Wide310x150Logo="Images\Wide310x150Logo.png" Square310x310Logo="Images\LargeTile.png"/>
<uap:SplashScreen BackgroundColor="white" Image="Images\SplashScreen.png" a:Optional="true"/>
</uap:VisualElements>
<Extensions>
<uap:Extension Category="windows.appService" >
<uap:AppService Name="BidirectionalCom" uap4:SupportsMultipleInstances="false"/>
</uap:Extension>
</Extensions>
</Application>
Doing that works as far as launching the fulltrust project, and establishing the connection, with a call to OnBackgroundActivated(BackgroundActivatedEventArgs args). There, I can succesfuly send a request and get an answer.
But I hit two major problems:
- Any (static or instance) field or event instantiated in app.xaml.cs of the UwpUI project is null when it is called from another method, including the reference to the connection.
- Prior to the modification, in debug mode at least, I could set breakpoints in both the UWP and the .NET framework project by doing 'detach all', then 'attach to process'. Now When attaching, the .NET framework project is greyed out.
Any idea what I'm missing? Problem 1 is the worse, since it breaks the app, but I need to solve the two. Thank you.
EDIT : When looking at Task Manager, I see two processes with the same entry point (UwpUI.exe). Indeed, breakpoints show me that the call to the uwp constructor ( App.xaml.cs.App()), is called twice. That certainly explains problem 1: fields are set in one instance and are of course null in the second instance. Seems I need to structure my manifest differently, but I have yet to find how.
EDIT: Example project Here