Registration-free COM with Azure App Services
TL;DR: If you ever got this error on Azure App Services, read-on: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
This is admittedly an esoteric topic, but useful to know in case you happen to hit it. Azure App Services are wonderful; they make it really easy to host a website or API in Azure, with the platform handling the "hard parts" of HTTPS certificate management, scaling, load balancing, etc. A few months ago, while working on my code signing service, I hit a strange issue when running on Azure that didn't reproduce locally. MakeAppx.exe, a tool that expands and creates AppX packages, was failing. The code signing service bundles a few utility exe's that are executed for certain operations. In this case, I needed to extract Appx/Appxbundle files, modify the contents and repack them.
When I started investigating, I went to the Kudu console and tried executing
makeappx.exe, I got the following error: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.. No combinations of parameters made a difference, it wasn't even getting that far.
After looking at potential differences in that application vs every other application that worked, I noticed that
makeappx.exe uses an embedded manifest that declares registration-free COM dependencies. This is because
makeappx.exe includes local copies of some files may be newer than the ones included in the operating system. If I replaced the built-in manifest with a default one, I could launch the application, so that was definitely the issue. The caveat is two-fold: 1. I was modifying a Windows SDK binary, and I didn't want to do that, 2. I'd be tied to a particular version of that tool that matched whatever app services was running on.
Given that I was now in uncharted territory, I reached out to the App Service team and they graciously helped. In particular, I need to thank David Ebbo and Petr Podhorsky, without whom I'd still be stuck.
What the investigation found: due to the way App Service maps in the "D" drive (the default one your site runs from). As Petr explains:
- Registration-free COM side-by-side is handled by a different process on the box, CSRSS, which runs under a different account and because the path is transferred between processes unchanged, it tries to look at
d:\homepath, which is a special path and makes sense only for your site process, but nothing else on the box (if there are multiple sites running on the box, they all have their own
d:\homeand don’t see each other’s content). So it does not find your manifest.
- Even if the previous problem was solved, the CSRSS (client server runtime subsystem) process does not have access to the site content anyway.
Fortunately, there is a workaround: use the
HOME_EXPANDED environment variable. That points to the real path of the "C drive" equivalent location, something like
C:\DWASFiles\Sites\#1mysite1\home. Don't worry about the exact location, just use the variable.
makeappx.exe from the
HOME_EXPANDED location works because CSRSS sees the files that the manifest points to and it loads properly. You can see how I applied the workaround here.
While it's likely rare to have a program using registration-free COM invoked on App Services, it's not entirely impossible. You might have a web job or function that needs to invoke some program, or you might need to invoke programs for some website functionality like I do. If you do hit this, I hope this workaround unblocks you too.