Advanced Problem-Solving Techniques for Installing Third-Party Software in Windows Containers
C2 Labs thrives on solving some of the most complex technical challenges that inhibit digital transformation within highly regulated industries. Over the past year, we have gained extensive experience in containerizing legacy Windows 2000 and 2003 applications to allow customers to move off of unsupported and insecure Windows operating systems. One of our top software engineers, Jason Phillips, has developed some guidance and best practices on containerizing Windows applications that is shared below.
While much of the containerization work in the commercial app world has focused on Linux, many large enterprises maintain a high number of Windows-based workloads. For that reason, one may be required to install applications and third-party software in a Windows container at some point in the future. This requirement presents a challenge as the third-party software must be successfully provisioned inside the container either by running the installation media in silent mode from the command line or directly copying the executable or DLL into the container, which can be a difficult task.
When using installation media and performing a silent install with no errors, the question becomes, did it install correctly? More often than not, when you run the application, it fails with no useful error output. The application will run correctly on a regular Windows Server installation and you have confirmed that the container environment was configured correctly. After querying the registry, you find that no registry keys were created during the installation. You may try to manually register the DLLs using regsvr32 but will find after querying the registry that they were not registered. Next, when you export the application’s registry configuration from a working machine and import that registry configuration into the Windows container registry, you will find that the application still does not work correctly. What do you do? Something is not working correctly, but how does one determine what is wrong? How does one debug the errors and ultimately fix them?
Our extensive experience containerizing Windows workloads has shown that the most likely causes of this problem are:
The application is missing dependencies which are not displayed in the log output.
Another application is actively preventing the containerized application from starting.
The rest of this blog post provides best practice solutions, the tools and techniques, that will allow you to effectively overcome these problems.
Solution #1: Process Monitor To The Rescue
Stefan Scherer wrote a blog post that describes how to find missing dependencies in Windows containers using Microsoft’s Process Monitor. His post offers excellent information which we can use to begin to solve the problem described above. We have supplemented Stefan’s post with additional guidance which will help you ultimately install any third-party application or service in a Windows container.
As Stefan describes, Process Monitor can be used to find missing dependencies. The steps to accomplish this task are:
Run Process Monitor on the Docker Windows host
Begin capturing all relevant process activity
Start the container application
Stop Process Monitor logging once the application has failed.
Review the Process Monitor log
The Process Monitor log will show every call and every resource requested by the kernel while it runs the containerized application. You may find that the kernel begins searching within a series of locations for a resource (either a DLL, executable or configuration file), but at some point, it cannot find this dependency and the thread will exit. To resolve this issue, you should copy the missing dependency into a folder inside the Windows container where the kernel was looking for it.
If your missing dependency is a DLL, and you copy the DLL into a Windows container, do you need to register it? While conventional wisdom states that one needs to use regsvr32.exe to register a DLL, our practical experience shows that Regsvr32 does not create a registry key in a Windows container. Likewise, importing the registry configuration from a working machine has no effect when the application is running.
If you inspect the Process Monitor log, you will find that the kernel searches a series of folders for a DLL and will fail the thread once it has exhausted all locations. Empirical observation shows that the DLL’s registry keys are irrelevant. The kernel searches the file system for the DLL and does not use the file location saved within the registry key. You simply need to place the DLL in a folder where the kernel is looking and the problem should resolve itself.
Solution #2: Dependency Walkers Are Helpful Too
If the Windows container is missing some DLLs on which your application’s DLLs depend, you can discover this using a DLL dependency walker. Multiple dependency walkers exist which allow one to inspect DLLs and discover useful information like:
Inspect a DLL to ensure that its dependencies exist in the container’s system32 or syswow64 folders.
Inspect whether the DLL was compiled with a 32- or 64-bit compiler.
The Windows Docker images provided by Microsoft do not include every DLL that is found in a full Windows Server operating system install. For example, if your application requires the Visual C++ DLL, you may be missing DLLs on which that Visual C++ DLL version depends. You will need to copy the missing dependencies into the container, placing them into the appropriate folder as shown by the dependency walker. It is worth noting, contrary to what their names suggest, 64-bit DLLs belong in c:\windows\system32 and 32-bit DLLs belong in c:\windows\syswow64.
Solution #3: The Overly Zealous Security Software
Any antivirus or endpoint protection software running on the host has visibility over processes running in Docker containers on that host. An unregistered process running inside the container may draw attention from the host’s security software and possibly block the application’s execution in the container.
If no dependencies are missing and the container application still refuses to start, inspect the antivirus or endpoint protection software logs as it may be the culprit. Review the Process Monitor logs and search for your container applications’s process. If you see its execution being pre-empted by processes originating from your antivirus or endpoint protection software, you will need to work with your security team administrators to create prudent exceptions in the antivirus or endpoint protection policies that allow for safe execution.
Once the missing dependencies have been copied to the correct locations, you’ve confirmed nothing is blocking execution and the container and host are in a happy state, the application should then run in the Windows container with no problem.
At C2 Labs, we love pushing technical boundaries and solving the most complex business problems. We have worked with our clients to containerize even the most challenging Windows applications (including Windows 2000 and 2003 Server applications and services). We would love to talk you about how we can accelerate your organization’s digital transformation. Please contact us to learn more.