Attempting to run embedded tool from WIX msi for s

2019-09-14 18:08发布

问题:

Basically I'm trying to build a WIX msi that can run devcon.exe (command line version of windows hardware manager) to detect if a particular piece of hardware is installed. If it is, then install msi A, else install msi B (A and B already exist as separate msi packages, we need automatic selective installation based on the hardware).

Currently I've installed the WIX SDK and have created a WIX project that correctly builds an msi. I can do simple things like execute CustomActions to open notepad.exe, that kind of simple things.

1st problem: I'm having trouble finding out how to package a file into the installer that isn't going to be installed into a directory. I've found references to it, but nowhere that explicitly states how to do it. I don't have to put it inside 'Directory' tags, if it's not going to be installed onto the host drive, right?

2nd problem: devcon.exe doesn't (from what I can tell, correct me if I'm wrong) seem to change it's return value depending on what it finds, probably because it does so many things and isn't restricted to whether a hardware device exists or not. So if I can get it embedded and get it to run, then I need to somehow take what it outputs to the standard output stream, and then parse it for the particular values that I'm looking for.

Of course it would be a bit easier because I've already got a batch file that can do the parsing and set an environment variable which will tell me what I need to know, but, if I can embed them both, how do I get the batch file to reference the embedded devcon.exe, and then get WIX to read the variable, or perhaps I can set one up (or a property) in WIX and then set it from the batch file?

Maybe I should create a dll custom action instead? Is it possible to run an embedded executable from a dll custom action? Then I could run devcon.exe, and do all the parsing in there, then simply set a Wix variable or Property to choose what to do next.

3rd problem: being able to run one msi from another. I'm not quite upto this yet, but I've found (http://softwareinstall.blogspot.com/2008/06/fun-with-msiembeddedchainer.html) which looks promising, although I haven't read through it all yet. One problem at a time, I've certainly got enough already :)

回答1:

Okay, first problem is solved:

<Binary Id="Devcon" SourceFile="D:\Programming\Device_Selection\Device_Selection\devcon.exe"/>
<CustomAction Id="RunDevcon" BinaryKey="Devcon" ExeCommand="resources *vendor*device*" Return="check" Execute="deferred" Impersonate="no" />

This ensures that the devcon.exe tool is embedded in the installer and that I can run it in administrator mode (which doesn't work unless you specify Impersonate to "no" and Execute to "deferred").

The next thing I need to do is be able to read the output that devcon usually send to the console (ie. cmd window) and then parse it for information. Is there a way to capture that output?



回答2:

For the 2nd problem, I'd create an EXE or DLL custom action which starts devcon.exe, reads its output and parses it. The devcon.exe itself could be stored in resources of EXE/DLL and extracted into a temporary directory before starting, then you remove it when done with it.

If you choose DLL, you can change MSI public properties. That way you can set a property which will control what will be done next in the MSI.

If you choose EXE, all you have is exit code. As far as I know there's not much you can do with it actually in MSI.


Chaining MSI installs is not recommended. You can embed both drivers into one package and select which components to install depending on the property set as the result from devcon.exe detection.


Another approach would be to create a bootstrapper EXE which runs devcon.exe and determines which package to install. Then it simply installs the correct MSI package.