Since Adobe DC, I've seen a number of issues with printing or previewing PDF documents within our Desktop applications.
The desktop application was using the WebBrowser
component, but now we have moved it to use Adobe PDF Reader COM (axAcroPDF
) component to preview a PDF document.
Since the DC and the new component, I have seen that the Preview dialog takes x seconds to close down.
This happens once the document seems to have closed, but it's waiting for something before it closes the Winform. (This can make it look like the application has crashed! NOT GOOD)
Now I have been able to create a solution which will close the PDF document and kill the Adobe process. This is only the processes which are linked to the Parent Winform application. All other PDF Document or Adobe process are left alive.
Get the Parent Id from Process
This get the current application process Id (Parent Process Id) from the system processes
private static int GetParentProcessId(Process p)
{
int parentId = 0;
try
{
ManagementObject mo = new ManagementObject("win32_process.handle='" + p.Id + "'");
mo.Get();
parentId = Convert.ToInt32(mo["ParentProcessId"]);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
parentId = 0;
}
return parentId;
}
Reference required: System.Management
Get PDF Document title
If the document contains a title, the below logic uses ITextSharp to interrogate the PDF
private static void getDocumentTitle()
{
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(documentPath);
documentTitle = reader.Info["Title"];
}
Kill the Process
Below method kill a single process
private static void killSingleProcess(Process process)
{
try
{
if (process != null)
{
process.Kill();
}
}catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
Get the Adobe Process
This is where all the bits come to gather!
It will get all Adobe process, the Parent Process id and then it will kill all processes linked to the parent process ID
public static void Adobe(string path)
{
documentPath = path;
Utilities.DebugSolution.SetMessageUniqueFile("Printing", "Kill Adobe process");
try
{
processes = Process.GetProcessesByName("AcroRd32");
var desktopProcess = Process.GetProcessesByName("[DESKTOP PROCESS NAME]");
getDocumentTitle();
if(desktopProcess != null || desktopProcess .Count() >0)
{
var desktopProcessId = hdProcess[0].Id;
foreach (Process process in processes.Where(x => x.MainWindowTitle.Equals(documentTitle, StringComparison.OrdinalIgnoreCase) || x.MainWindowTitle.Equals("")).ToList())
{
var parentProcess = GetParentProcessId(process);
if(parentProcess.Equals(desktopProcessId))
{
killSingleProcess(process);
}
}
}
}catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}