1

My batch file that I'm trying to run when an Excel plugin needs to be uninstalled is not executing. I'm using the following custom actions to do post install and also on uninstalling the product. The following code:

  <CustomAction Id="registeraddin" ExeCommand="[INSTALLFOLDER]RegisterMilerAddIn.bat" Directory="INSTALLFOLDER" Impersonate="no" Execute="deferred" Return="asyncWait" />
  <CustomAction Id="unregisteraddinpostinstall" ExeCommand="[INSTALLFOLDER]UnRegisterMilerAddIn.bat" Directory="INSTALLFOLDER" Impersonate="no" Execute="deferred" Return="asyncWait" />

  <InstallExecuteSequence>
    <Custom Action="registeraddin" After="InstallFiles">NOT Installed</Custom>
    <Custom Action="unregisteraddinpostinstall" After="InstallFiles">Installed AND (REMOVE = "ALL")</Custom>
  </InstallExecuteSequence>

Produces this error in the log:

MSI (s) (44:04) [11:29:00:437]: Executing op: ActionStart(Name=unregisteraddinpostinstall,,)

MSI (s) (44:04) [11:29:00:437]: Executing op: CustomActionSchedule(Action=unregisteraddinpostinstall,ActionType=1058,Source=C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\,Target=C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\UnRegisterMilerAddIn.bat,)

MSI (s) (44:04) [11:29:00:846]: Note: 1: 1722 2: unregisteraddinpostinstall 3: C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\ 4: C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\UnRegisterMilerAddIn.bat

MSI (s) (44:04) [11:29:00:846]: Note: 1: 2205 2: 3: Error MSI (s) (44:04) [11:29:00:846]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1722 CustomAction unregisteraddinpostinstall returned actual error code 100 (note this may not be 100% accurate if translation happened inside sandbox)

MSI (s) (44:04) [11:29:10:900]: Note: 1: 2205 2: 3: Error MSI (s) (44:04) [11:29:10:900]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1709

MSI (s) (44:04) [11:29:10:900]: Product: WebMiles_Addin_Installer -- Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action unregisteraddinpostinstall, location: C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\, command: C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\UnRegisterMilerAddIn.bat

That error is obscure to me. I'm not doing real fancy stuff in my batch file either. The installation of the Excel addin works fine (which is the premise of this application). But I can't uninstall the addin, apparently, in the same manner, so goes the aforementioned error in the log.

For completeness, this is the contents of of my register batch (RegisterMilerAddIn.bat):

SET WorkFolder= "C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin"

SET _NET_4_Folder= %WinDir%"\Microsoft.NET\Framework\v4.0.30319"

%_NET_4_Folder%\regasm.exe %WorkFolder%\Miler.ExcelAddin.dll /Codebase /tlb:%WorkFolder%\Miler.ExcelAddin.tlb >> C:\temp\log.txt

And unregister batch (UnRegisterMilerAddIn.bat):

SET WorkFolder= "C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin"

SET _NET_4_Folder= %WinDir%"\Microsoft.NET\Framework\v4.0.30319"

%_NET_4_Folder%\regasm.exe /unregister %WorkFolder%\Miler.ExcelAddin.dll /Codebase /tlb:%WorkFolder%\Miler.ExcelAddin.tlb >> C:\temp\log.txt
Fus Ro Dah
  • 331
  • 5
  • 22
  • RemoveFiles is scheduled before InstallFiles so your bat file doesn't exist when you try to run it. Schedule your action `Before="RemoveFiles"` – Brian Sutherland Jun 26 '18 at 20:32
  • You should learn to use the recommended syntax, with special regard to the placement of doublequotes. For example: `SET "WorkFolder=C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin"`, `SET "_NET_4_Folder=%SystemRoot%\Microsoft.NET\Framework\v4.0.30319"` and `"%_NET_4_Folder%\regasm.exe" "%WorkFolder%\Miler.ExcelAddin.dll" /Codebase /tlb:"%WorkFolder%\Miler.ExcelAddin.tlb">>"C:\temp\log.txt"` – Compo Jun 26 '18 at 20:38
  • Thanks @BrianSutherland, I tried that and I'm not getting an error anymore (that I can see. The uninstall exiting with "Removal success or error status: 0.") Also, thanks for the heads up Compo, it's not my script I wrote and I haven't really reviewed bat syntax thoroughly. I just know that the batch file executes and does what it's supposed to when kicked off manually. – Fus Ro Dah Jun 26 '18 at 20:43
  • The batch file is still only registering the addin, but not successfully unregistering, unfortunately – Fus Ro Dah Jun 26 '18 at 20:45

2 Answers2

2

Heat.exe

UPDATE: I didn't like what I suggest below (custom action use), and Bob Arnson (WiX coder) reminded me that heat.exe (WiX's general purpose "harvester" / XML markup generator tool) might do the job:

heat.exe file MyLib.dll -sfrag -suid -ag -out ComInterop.wxs

If this works - which you should test - you have removed a whole lot of "clunk" from your WiX installer.

You need to slipstream the generated COM / registry information into the component hosting your COM Interop file in your main WiX source file. This requires some care and precision and is not quite trivial, but you avoid a lot of clunky custom action risk.

You can also heat.exe the tlb file:

heat file MyFile.tlb -sfrag -suid -ag -out ComInterop2.wxs

It seems interface information is skipped by heat.exe.


Batch Files Considered Harmful

With all due respect, and with the intent to try to be helpful: batch files can be extremely error prone for deployment. They feature almost no error control or ability to handle unexpected conditions. I consider them undesirable for modern deployment and I think it is a consensus opinion.

You should be able to call regasm.exe directly via an EXE custom action - eliminating all batch file-clunk and complexity. For the record: I don't like EXE CAs either though.

Enough opinions. Here is a basic mock-up example of EXE CAs for insertion into a full-blown WiX source (What characters do I need to escape in XML documents?):

<..>

    <!-- AppSearch to find regasm.exe -->

    <Property Id="REGASM4" Secure="yes">
        <DirectorySearch Id="RegAsmPathx86" Path="[WindowsFolder]Microsoft.NET\Framework\v4.0.30319">
            <FileSearch Name="regasm.exe" />
         </DirectorySearch>
    </Property>

<..>

    <!-- Run regasm.exe CAs -->

    <CustomAction Id="Install" Directory="SystemFolder"
                  ExeCommand="&quot;[REGASM4]&quot; &quot;[MyAPP]ClassLib.dll&quot; /Codebase /silent /tlb:&quot;[MyAPP]ClassLib.tlb&quot;"
                  Execute="deferred" Impersonate="no" />

    <CustomAction Id="Uninstall" Directory="SystemFolder"
                  ExeCommand="&quot;[REGASM4]&quot; /unregister &quot;[MyAPP]ClassLib.dll&quot; /Codebase /silent /tlb:&quot;[MyAPP]ClassLib.tlb&quot;"
                  Execute="deferred" Impersonate="no" />
 <..>

   <!-- Sequenced And Conditioned CAs -->

    <InstallExecuteSequence>
        <Custom Action="Install" After="InstallFiles">Not Installed</Custom>
        <Custom Action="Uninstall" Before="RemoveFiles">REMOVE~="ALL"</Custom>
    </InstallExecuteSequence>
Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • Very nice thank you for the suggestions and example. +1 for the installation and uninstallation through custom actions. I've been trying to convert all of our apps from a batch/exe setup to using msi. I'm liking what you can do with it, so far, such as what you've shown in your example. – Fus Ro Dah Jun 29 '18 at 14:19
  • 1
    Come to think of it I added a new section on top based on `heat.exe` - a WiX tool used to harvest WiX markup code. [**Avoiding custom actions is always a good thing**](https://stackoverflow.com/a/46179779/129130). `Use them when you really have to`. Whenever there is a built-in feature - prefer them. – Stein Åsmul Jun 29 '18 at 14:33
  • When they said WiX was a steep learning curve, take heed. Due to deadlines and my caution not to destroy my registry I will just keep your heat.exe addition as reference for future implementation or deployments. Is there a documentation link to all the parameters: `heat.exe --help` – Fus Ro Dah Jun 29 '18 at 14:51
  • Yes, we all have deadlines. You can get the parameters from the `heat.exe` itself, yes (In a cmd.exe: `heat.exe /?`), and you can [see it online as well](http://wixtoolset.org/documentation/manual/v3/overview/heat.html). I think `heat.exe` has some issues with 64-bit COM files (might be resolved by now). – Stein Åsmul Jun 29 '18 at 14:53
0

After researching and trying many different atrributes, I found a solution to my problem. So I'm posting it here may it help someone else. I was finding that my batch file was being deleted before I could run the addin uninstall process, as Brian Sutherland eluded to. I finally found the following code executed at a time in the uninstall that was before the removal of all the files.

<InstallExecuteSequence>
    <Custom Action="unregisteraddinpostinstall" After="InstallInitialize">REMOVE="ALL"</Custom>
  </InstallExecuteSequence>

So I will still be using the above code, but I am going to implement Stein Asmul's suggestions to clean up my process and not use a batch file. The reason I am still using After="InstallInitialize" is my ExcelAddin.dll is also part of the regasm.exe /unregister process to remove Type Class Libraries. It too was being deleted before I could run the script. After I implemented After="InstallInitialize">REMOVE="ALL", the script is working as expected. Thanks again to Brian and Stein!

Fus Ro Dah
  • 331
  • 5
  • 22
  • [This answer](https://stackoverflow.com/a/17595951/2196675) discusses a similar situation I'm running into... Also touches on upgrading situations. – Fus Ro Dah Jun 29 '18 at 20:51