Forum Discussion
MSIX .wapproj service
My agency is trying to move their services to MSIX/UWP and we found that the VisualStudio .wapproj .appxmanifest templates $targetnametoken$ and $targetentrypoint$ do not work for the properties 'Executable' and 'Entrypoint' of 'desktop6:Extension' tags with 'Category="windows.service"' despite working as expected on the enclosing 'Application' object.
Can someone who knows how this is intended to work please help?
I'm desperate at this point.
7 Replies
DataBen If you share the manifest (package.appxmanifest) I can take a look at it. You did add the capabilities to allow for the service, right?
- DataBenCopper Contributor
Thanks you for waiting.
This is the cleaned appxmanifest:
<?xml version="1.0" encoding="utf-8"?> <Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap rescap"> <Identity Name="Service" Publisher="CN=Company" Version="0.0.0.0"/> <Properties> <DisplayName>Service</DisplayName> <PublisherDisplayName>Company</PublisherDisplayName> <Logo>logo.png</Logo> </Properties> <Dependencies> <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0"/> <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.14393.0"/> </Dependencies> <Capabilities> <rescap:Capability Name="packagedServices"/> <rescap:Capability Name="runFullTrust"/> </Capabilities> <Applications> <Application Id="App" Executable="SomeApp.exe" EntryPoint="Program"> <uap:VisualElements DisplayName="Service" Description="Service" BackgroundColor="transparent" Square150x150Logo="large.png" Square44x44Logo="small.png"/> <Extensions> <desktop6:Extension Category="windows.service" Executable="SomeApp.exe" EntryPoint="Program"> <desktop6:Service Name="Service" StartupType="manual" StartAccount="localService"/> </desktop6:Extension> </Extensions> </Application> </Applications> </Package>
Assuming that the mentioned files and publisher exist, this packs as expected.
It gets interesting when the following two attributed are changed:
<Application Executable="SomeApp.exe" [...] <Extension Executable="SomeApp.exe" [...]
This combination works:
<Application Executable="$targetnametoken$.exe" [...] <Extension Executable="SomeApp.exe" [...]
While this one returns an error:
<Application Executable="SomeApp.exe" [...] <Extension Executable="$targetnametoken$.exe" [...]
The returned error is:
The file name "$targetnametoken$.exe" declared for element "*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='Extensions']/*[local-name()='Extension' and not(@Category='windows.backgroundTasks' or @Category='windows.appService')]" doesn't exist in the package.
It looks like you found your answer, or at least one that you can use for now.
That would be a problem that whoever owns the WAP project at Microsoft would need to fix. They aren't going to see this here, so you might want to report it (especially with the detail above) on a dev channel that they are listening on. (Sorry, but I don't know where that would be).
- DataBenCopper Contributor
Thank you very much for taking the time.
Unfortunately I won't be able to follow-up with the file until monday, but I'll describe it for you in the meantime:
In a VisualStudio solution containing two projects: One being the .wapproj, the other being the service, and with the wapproj having a project reference to the service, this is what works as expected:
The appxmanifest can contain placeholders inside a declared Application element.
This then directly uses the output of the referenced project's build, without a need to explicitly copy the bin files over to a folder inside the wapproj. Put simply: The tooling manages the linking, without a need for custom build steps. There is no danger of using outdated files, or breaking the build by refactoring something.
Here is where my naive assumptions deviate for reality:
Inside an appxmanifest, an Application element can contain a windows service as an extension. (Application element>Extensions element>Extension element with Category="windows.service").
That extension expects, just like the application element containing it, an Executable and an Entrypoint property linking to an executable file.
If that executable file mentioned in those properties is found within the wapproj's files then the msix package builds and the application and service install as expected.
However, using the same placeholders (eg. $targetnametoken$) inside the Extension elements properties will *not* link the build output to the bundled service, and instead error with a message along the lines of 'file with name $targetnametoken$ not found in project'.
Is there an intended way to link build outputs to bundled services?
If not, is there possibly a .targets file I could take inspiration from?
Again, I'll follow-up with the appxmanifest file on monday. I wish you a great weekend.
Cheers, Ben.
In all likelihood your service wants to start under the SystemServices logon account. In that case, there are two capabilities that must be added to the manifest:
<rescap:Capability Name="localSystemServices"/>
<rescap:Capability Name="packagedServices"/>
Depending on the scenario, you could also consider rewriting the service as "out of process COM" instead of a service.
- Services are available for interaction to software outside of the MSIX container, and have system privileges to perform actions on behalf of the user without UAC prompts.
- Out-of-Process COM supports calls from inside the package that can perform system privileges to perform actions on behalf of the user without UAC prompts.
While I wouldn't re-write without a reason, there are some situations in an MSIX package where when the service doesn't cut it, the out of process COM can. Most likely, you just need the second capability for localSystemServices.