Introduction
My team recently encountered an issue related to Active PDF in an ASP.NET based application (which wasn’t cloud native and containerized) that was a bit tricky to identify and resolve. The main issue was that the API was consistently returning a -1
on certain environments with no additional details related to the type of failure.
While resolving the issue, we uncovered facts and tactics I wanted to share with the broader community, specifically with IIS and ActivePDF. Following were the key findings:
- The main reason behind failures was due to version conflicts, yes even though the DLLs were included as part of the web application.
- Windows uses DLLs in two different folders based on System32, SysWOW64 folders based on the run-mode of the application.
- Since the environment where the application was failing was controlled, we had to create a sample test application that could be easily deployed and tested without a full build cycle.
Problem
One of the features required reading a standard PDF template from a remote service, updating it with user data, and publishing it. The templates were password protected.
This seemed to work on local developer workstations, however on the shared environments INT, QA it was failing. Following was the code snippet:
using (var tookit = new APToolkitNET.Toolkit())
{
int inputfile;
int copyForm;
toolKit.SetInputPasswords("", );
**open input file**
toolkit.InputByteArray = ;
inputfile = toolkit.OpenInputFile("MEMORY");
if (inputfile!= 0)
{
}
}
The OpenInputFile
statement was consistently returning a non-zero input on certain environments. The Active PDF documentation indicates few reasons behind this but nothing conclusive (link below):
Approach
- Since the environment was controlled, making any changes, deploying and testing required a lot of time. We first decided to speed up the process.
- We created a simple ASP.NET MVC that read a local PDF file to try and reproduce the issue.
- Then with help of the operations team, we setup a process that allowed quick deployment of this application (basically with direct access to the web root of the application). This allowed us to make quick changes, deploy and test quickly.
- With the new process in place, we tried multiple permutations and combinations and tried to replicate the issue consistently. We found that it would fail consistently when the file had a password.
- To compare what was different across the developer workstation and shared environments, we then decided to log the version of the API being used. One of the great features that helped was checking the version of the toolkit, we used this to log the version of the API being used.
- With this, we noticed that the version on common environments was an outdated version. This confirmed that it was indeed because the version. We then tried to replicate this locally, by replacing some of the installed DLLs.
- The next step was to understand why the old version was being referenced. The latest version was installed on the shared environments and the latest DLLs were also included as part of the web application (bin folder). We looked closely at all the DLLs installed by the toolkit and found that the API has two tier/layers:
- Wrapper API – this is part of .NET
- COM API – This comprised of the following DLLs and they are deployed in the system folders and they seemed to be referenced from the system folders:
- APTK5
- APT50
- APTDBU64
- We then searched on the shared environments for all versions of these DLLs and found that the older versions were in the C:\Windows\ SysWOW64 (This folder is used when app runs in 32-bit mode). The primary issue was thus that the application pool on the shared environments was 32-bit and the older version of APIs still lying in SysWOW64 folder.
- We replaced the DLLS in SysWOW64 since the application pool change would impact other applications.
Takeways
- Find creative ways to speed up debugging complex tricky issues, especially on environments when application isn’t containerized and access is limited.
- Log as much detail as possible.
- Bear in mind the differences between
System32
and SysWOW64
folders link
History
- 2nd December, 2016: Initial version