1
votes

I want to open a PDF file after my WiX installer completes.

The relevant WiX XML I currently have is:

<Property Id="WixShellExecTarget" Value="[#Manual.pdf]" />

<CustomAction Id="ShowManual" 
    Return="ignore" 
    BinaryKey="WixCA"
    DllEntry="WixShellExec" 
    Impersonate="yes" />

<InstallExecuteSequence>
    <Custom Action="ShowManual" After="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>

This all works fine on machines where a PDF reader is installed. But if not, Windows is flashing up a message saying 'Windows can't open this type of file'.

Is there any way to get WiX to only attempt the call to ShellExecute if there is an application associated with PDF files? Or is it possible to get the call to fail silently without displaying any errors?

1
Couldnèt you do a RegistrySearch to see if the extension is handled and make it a condition for your CustomActionCheGueVerra
@CheGueVerra I hadn't thought of that, but I understand that the required registry key can change dependent on the version of Windows. I'd rather avoid the registry if possibleCocowalla
You could detect the Version of Windows search the corresponding registry values. Otherwise I don't see how you can check if you can open the PDFCheGueVerra
I don't think the location changes on different version Windows, but I haven't checked. Looking for something under HKCR\.pdf would be a place to start, but you're right in that it might not be reliable. Otherwise you'd need to run code that does a ShellExecute on pdf first before trying to open the pdf.PhilDW
@PhilDW I've checked, and the HKCR\.pdf value is not set on Windows 8, so there are differences between different versionsCocowalla

1 Answers

-1
votes

I solved this by creating an 'immediate' managed custom action that runs after InstallFinalize and uses FindExecutable to check if an application is associated with PDF files before trying to open it:

[DllImport("shell32.dll", EntryPoint = "FindExecutable")]
private static extern long FindExecutable(string lpFile, string lpDirectory, StringBuilder lpResult);

[CustomAction]
public static ActionResult ShowPdf(Session session)
{
    var installDir = session["INSTALLDIR"];
    var pdfPath = Path.Combine(installDir, @"My Dir\My.pdf");

    var pdfReaderPath = new StringBuilder(1024);
    long lngResult = FindExecutable(pdfPath, String.Empty, pdfReaderPath);

    if ((lngResult >= 32) && (!String.IsNullOrWhiteSpace(pdfReaderPath.ToString())))
    {
        Process.Start(pdfPath);
    }

    return ActionResult.Success;
}