2

I have a UWP app that has 2 main parts, a UWP project that has the UI and a WinForms project that is used to provide system tray functionality. I am using a Windows Application Packaging project to join these together as in this example: https://learn.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-extend#show-a-modern-xaml-ui .

When the app launches the WinForm app is launched first and resides in the system tray. When one of it's menu options is selected the UWP app is launched and navigates to the appropriate page using the protocol approach from the example (ie Windows.System.Launcher.LaunchUriAsync("myapp://action?key=value");). This is working fine.

The problem I have is that I would like to be able to communicate from the UWP app to the WinForms app (maybe the other way too in some cases). I am trying to achieve this using the App Service extension. I have been following the example here: https://stefanwick.com/2017/06/24/uwp-app-with-systray-extension/ . However I cannot get this to work. I'm not quite sure which project the fulltrust and app service declarations should be in.

If I put them in my UWP project as in the example I always get an AppServiceUnavailable error (the name is definitely correct - I have no idea what the version that the documentation for this status refers to but I can't see how it can be incorrect). This happens regardless of whether the UWP app is open at the time or not. Previously I have got this approach working but only when there was no Windows Application Packaging project involved and the UWP app launched first which I don't want.

If I put the declarations in the Windows Application Packaging project (setting the app service executable and entry point to the UWP project App class), I get an AppUnavailable error which I guess means it's failing at an earlier point.

Does anyone know how I can get this working? If it's not possible for some reason can anyone point me in the right direction for achieving this idea (a UWP app that does not launch any windows on startup and resides in the system tray with bi-directional messaging between any components required).

EDIT: Target version: 17763, Min version: 16299, Windows version: 17763

EDIT2: I've created a small test solution that hopefully shows what I'm trying to do better: https://github.com/csuzw/AppServiceTest .

rcarrington
  • 1,485
  • 2
  • 12
  • 23
  • What's your project's target and min version? And what's your OS build version? – Xie Steven Mar 11 '19 at 00:25
  • @XavierXie-MSFT added version information to question – rcarrington Mar 11 '19 at 09:04
  • Please check if you have created the AppService correctly like the [demo](https://github.com/Microsoft/DesktopBridgeToUWP-Samples/blob/master/Samples/UWP%20Systray/SystrayExtension/App.xaml.cs#L57). – Xie Steven Mar 11 '19 at 09:09
  • @XavierXie-MSFT Yes I followed that example (via Stefan Wick's blog post). There is a difference in my example though and that is that I'm using a Windows Application Packaging project. This allows me to have the WinForms app start first and the UWP app not launch until I need it. However none of t he demos other than the first one I posted in my question use this. – rcarrington Mar 11 '19 at 09:17
  • @XavierXie-MSFT I've create small test app that hopefully shows what I'm trying to do better. I'm pretty much at my wits end now, none of the samples show this scenario (as far as I can tell). The existing systray samples really don't have great behaviour in my opinion. I've even resorted to trying Named Pipes to communicate between the apps but I can't get that working either even though there is documentation to suggest that if the name is prefix LOCAL\ this should work between apps in the same app package. – rcarrington Mar 12 '19 at 11:04

1 Answers1

2

Ok. I've checked your demo. After consulting with Stefan Wick, the issue is able to be resloved.

You would need to make the following change to the Package.appxmanifest file of the WAP project. Otherwise, VS will declare the AppService on the Winforms app, which won't work.

<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
  <uap:VisualElements DisplayName="AppServiceTest" Description="AppServiceTest" BackgroundColor="transparent" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png">
    <uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png">
    </uap:DefaultTile>
  </uap:VisualElements>
</Application>
<Application Id="App2" Executable="AppServiceTest.UI.exe" EntryPoint="AppServiceTest.UI.App">
  <uap:VisualElements AppListEntry="none" DisplayName="WapProjTemplate1" Description="WapProjTemplate1" BackgroundColor="transparent" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png">
    <uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
  </uap:VisualElements>
  <Extensions>
    <uap:Extension Category="windows.appService">
      <uap:AppService Name="MyAppServiceName"  />
    </uap:Extension>
    <desktop:Extension Category="windows.fullTrustProcess" Executable="AppServiceTest.Systray\AppServiceTest.Systray.exe"/>
  </Extensions>
</Application>
Xie Steven
  • 8,544
  • 1
  • 9
  • 23
  • I think I need my AppService to be in-process as I need my UWP app to be able to react to the messages that are received - unless I'm misunderstanding what in-process and out-of-process mean? – rcarrington Mar 11 '19 at 11:57
  • Regarding the UWP app needing to run once: If I don't want the UWP app to show anything at startup, is there a way to achieve this? As far as I can tell launching the UWP app always shows the window. Also as I said in my question, even after I've launched the window, I'm not getting connections created (OnBackgroundActivated never seems to get called). – rcarrington Mar 11 '19 at 12:03
  • @rcarrington I've updated my reply. Please check it. – Xie Steven Mar 15 '19 at 02:54