How do I run the setup.exe from the command line for silent install/uninstall?

Add-in Express™ Support Service
That's what is more important than anything else

How do I run the setup.exe from the command line for silent install/uninstall?
 
John Zabroski




Posts: 12
Joined: 2019-08-29
I tried to run this from the command line but it doesn't seem to do anything.
Posted 29 Oct, 2019 10:43:56 Top
Andrei Smolin


Add-in Express team


Posts: 18823
Joined: 2006-05-11
Hello John,

I would check that a non-silent version of your installer works correctly.


Andrei Smolin
Add-in Express Team Leader
Posted 30 Oct, 2019 03:42:26 Top
John Zabroski




Posts: 12
Joined: 2019-08-29
Hi Andrei,

Non-silent version of the installer works correctly. Here are the steps I did prior to creating this post:


  • Confirmed the non-silent version of setup.exe works correctly
  • Explored how to use setup.exe from the command line.
    [LIST]
  • Opened PowerShell Core
  • Changed current working directory to the path of setup.exe
  • Ran .\setup.exe /?
  • Got following screenshot https://imgur.com/a/TaA4bvy
  • Noted the message at the bottom of the screenshot: "All remaining command line arguments will be passed to the application install." <== THIS DOES NOT SEEM TO BE WORKING CORRECTLY

  • Tried .\setup.exe -componentsurl and see that there are no external components created by the Wix Installer (this much I expected based on how I see the AddInExpress dll's bundled, but maybe you don't expect this as the AddInExpress guru?).
  • Tried testing executing the msi directly. (My MSI is called SubscriberRTDAddinSetup(2.0.0).msi as it's intended to allow RTD calls as a form of pub-sub cache)

    • & '.\SubscriberRTDAddinSetup(2.0.0).msi' /?
    • I get the options, pasted below as a quote:
      Windows ??? Installer. V 5.0.17763.404

      msiexec /Option <Required Parameter> [Optional Parameter]

      Install Options
      </package | /i> <Product.msi>
      Installs or configures a product
      /a <Product.msi>
      Administrative install - Installs a product on the network
      /j<u|m> <Product.msi> [/t <Transform List>] [/g <Language ID>]
      Advertises a product - m to all users, u to current user
      </uninstall | /x> <Product.msi | ProductCode>
      Uninstalls the product
      Display Options
      /quiet
      Quiet mode, no user interaction
      /passive
      Unattended mode - progress bar only
      /q[n|b|r|f]
      Sets user interface level
      n - No UI
      b - Basic UI
      r - Reduced UI
      f - Full UI (default)
      /help
      Help information
      Restart Options
      /norestart
      Do not restart after the installation is complete
      /promptrestart
      Prompts the user for restart if necessary
      /forcerestart
      Always restart the computer after installation
      Logging Options
      /l[i|w|e|a|r|u|c|m|o|p|v|x|+|!|*] <LogFile>
      i - Status messages
      w - Nonfatal warnings
      e - All error messages
      a - Start up of actions
      r - Action-specific records
      u - User requests
      c - Initial UI parameters
      m - Out-of-memory or fatal exit information
      o - Out-of-disk-space messages
      p - Terminal properties
      v - Verbose output
      x - Extra debugging information
      + - Append to existing log file
      ! - Flush each line to the log
      * - Log all information, except for v and x options
      /log <LogFile>
      Equivalent of /l* <LogFile>
      Update Options
      /update <Update1.msp>[;Update2.msp]
      Applies update(s)
      /uninstall <PatchCodeGuid>[;Update2.msp] /package <Product.msi | ProductCode>
      Remove update(s) for a product
      Repair Options
      /f[p|e|c|m|s|o|d|a|u|v] <Product.msi | ProductCode>
      Repairs a product
      p - only if file is missing
      o - if file is missing or an older version is installed (default)
      e - if file is missing or an equal or older version is installed
      d - if file is missing or a different version is installed
      c - if file is missing or checksum does not match the calculated value
      a - forces all files to be reinstalled
      u - all required user-specific registry entries (default)
      m - all required computer-specific registry entries (default)
      s - all existing shortcuts (default)
      v - runs from source and recaches local package
      Setting Public Properties
      [PROPERTY=PropertyValue]

      Consult the Windows ??? Installer SDK for additional documentation on the
      command line syntax.

      Copyright ??? Microsoft Corporation. All rights reserved.
      Portions of this software are based in part on the work of the Independent JPEG Group.


    [/LIST]
  • Posted 04 Nov, 2019 12:09:20 Top
    John Zabroski




    Posts: 12
    Joined: 2019-08-29
    Sorry my last post did not format super-great. I guess AddInExpress forums don't support nested BBCode tags.

    Anyway, here is the long and short:

    Works:
    
    # The following works
    & '.SubscriberRTDAddinSetup(2.0.0).msi' /qb! /l*vx install_log.txt
    


    Doesn't work:
    
    # The following DOES NOT work - WHY???
    .setup.exe /qb! /l*vx install_log.txt
    



    I then tried un-installing the msi package:

    
    # The following does not work
    msiexec.exe /X '.SubscriberRTDAddinSetup(2.0.0).msi'  /qb! /l*v uninstall_log.txt
    


    I found a DANGEROUS workaround: querying Win32_Product. Win32_Product should really not be queried, as it is not a read-only operation. Apparently, querying Win32_Product has the side-effect of running a consistency check on every package and then proceeds with repair installations if any are found. THIS MIGHT BE VERY DANGEROUS ON A PRODUCTION SYSTEM.

    
    # The following PowerShell script, VERY CONVOLUTED, does work.
    $packageToUninstall = $(get-wmiobject Win32_Product | Where-Object { $_.Name -ilike "SubscriberRTDAddin" } | Select-Object -First 1)
    .msiexec.exe /X $($packageToUninstall.LocalPackage)
    


    or, more simply:

    
    # The following PowerShell script, VERY CONVOLUTED, does work.
    $packageToUninstall = $(get-wmiobject Win32_Product | Where-Object { $_.Name -ilike "SubscriberRTDAddin" } | Select-Object -First 1)
    $packageToUninstall.Uninstall()
    


    My source for these answers was installdude.com's Stein Asmul posting on StackOverflow, here: https://stackoverflow.com/a/1055933/1040437
    Posted 04 Nov, 2019 13:43:19 Top
    Andrei Smolin


    Add-in Express team


    Posts: 18823
    Joined: 2006-05-11
    Hello John,

    I've got a word from our developers. They say the setup project that Add-in Express creates does not support silent installs: the actions are executed if properties are set by the user or pre-set by you.

    You may need to use WiX to modify the project so that it fulfills your requirements.


    Andrei Smolin
    Add-in Express Team Leader
    Posted 05 Nov, 2019 05:53:49 Top
    Andrei Smolin


    Add-in Express team


    Posts: 18823
    Joined: 2006-05-11
    Ah, sorry.

    Andrei Smolin writes:
    if properties are set by the user or pre-set by you.


    Correction: If properties are set by the user (who selects their values in the dialogs) or pre-set by you.


    Andrei Smolin
    Add-in Express Team Leader
    Posted 05 Nov, 2019 05:55:26 Top
    John Zabroski




    Posts: 12
    Joined: 2019-08-29
    How do I request that the developers support silent install?

    I've run into (and reported on these forums) several issues with the Add-In-Express Wix installer, as well as the basic fact the Visual Studio Installer is no longer supported by Microsoft and really doesn't work in Visual Studio 2019 even with the unsupported https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2017InstallerProjects (it sometimes loads when the Solution loads, and sometimes doesn't).

    I think we can all agree Wix is a huge pain-in-the-you-know-what, but Add-In-Express needs some good solution for helping customers package and install the plug-in.

    On top of this issue, I've also faced another issue I haven't even had time to report:

    To get the Wix project to build as part of our Continuous Delivery toolchain, I've had to edit the SubscriberRTDAddin.wixproj file. This is doubly annoying, because every time I change Dependencies to the plug-in in Visual Studio I need to regenerate the wixproj, because wixproj syntax is so incredibly complicated that I dare not edit the Product.wxs file manually. It would be a great improvement if the developers wrote a right-click in Visual Studio to "Update Wix Set-up" instead of "Create Set-up". "Update Wix Set-up" would then update _only_ the Product.wxs file so that my Dependencies (dll list) are refreshed.

    The modifications I make to the generated wixproj are based around the guidance given by Wix on how to integrate Wix into a build pipeline: https://wixtoolset.org/documentation/manual/v3/msbuild/daily_builds.html

    1. Open Setup.wixproj
    2. Update the top of the wixproj file to be:
    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <WixToolPath>$(SolutionDir)..ToolsWiX Toolset v3.11in</WixToolPath>
        <WixTargetsPath>$(SolutionDir)..ToolsWiX Toolset v3.11MSBuild†WiX3.xWix.targets</WixTargetsPath>
        <WixTasksPath>$(WixToolPath)wixtasks.dll</WixTasksPath>
      </PropertyGroup>
      <ItemGroup>
        <WixExtension Include="WixUIExtension">
          <HintPath>$(SolutionDir)..ToolsWiX Toolset v3.11inWixUIExtension.dll</HintPath>
          <Name>WixUIExtension</Name>
        </WixExtension>
        <WixExtension Include="WixNetFxExtension">
          <HintPath>$(SolutionDir)..ToolsWiX Toolset v3.11inWixNetFxExtension.dll</HintPath>
          <Name>WixNetFxExtension</Name>
        </WixExtension>
      </ItemGroup>

    3. Update the line below
    <!-- Extract the registy information from the list of COM files and store it to temporary XML files -->
    to say:
        <Exec Command="&quot;$(WixToolPath)heat.exe&quot; file &quot;%(ResolvedCOMFilelist.Identity)&quot; -sw -gg -sfrag -nologo -srd -out &quot;$(IntermediateOutputPath)Harvested XML_%(Filename).com.xml&quot;" IgnoreExitCode="false" WorkingDirectory="$(MSBuildProjectDirectory)" Condition="'%(ResolvedCOMFilelist.Identity)'!=''" />

    4. Update the line below
    <!-- Generate WSX files from project references -->
    to say:
    <Exec Command="&quot;$(WixToolPath)heat.exe&quot; project &quot;%(ProjectReference.FullPath)&quot; -projectname &quot;%(ProjectReference.Name)&quot; -pog %(ProjectReference.RefProjectOutputGroups) -gg -sfrag -nologo -out &quot;$(IntermediateOutputPath)Harvested XML_%(ProjectReference.Name).xml&quot;" IgnoreExitCode="false" WorkingDirectory="$(MSBuildProjectDirectory)" Condition="'%(ProjectReference.FullPath)'!='' And '%(ProjectReference.DoNotHarvest)'!='True' And '%(ProjectReference.ImportedFromVDProj)'=='True'" />
    <HeatProject Project="%(ProjectReference.FullPath)" ProjectName="%(ProjectReference.Name)" OutputFile="$(IntermediateOutputPath)Harvested XML_%(ProjectReference.Name).xml" ProjectOutputGroups="%(ProjectReference.RefProjectOutputGroups)" ToolPath="$(WixToolPath)" SuppressAllWarnings="true" AutogenerateGuids="false" GenerateGuidsNow="true" SuppressFragments="true" SuppressUniqueIds="false" Condition="'%(ProjectReference.FullPath)'!='' And '%(ProjectReference.DoNotHarvest)'!='True' And '%(ProjectReference.ImportedFromVDProj)'!='True'" />
    Posted 05 Nov, 2019 09:02:04 Top
    John Zabroski




    Posts: 12
    Joined: 2019-08-29
    I was able to run the following:

    
    .msiexec.exe /x '{88705C51-3B43-48DD-B17E-00183E63D8A5}' /QN /L*VX ".uninstall_log2.txt" REBOOT=ReallySuppress
    


    where 88705C51-3B43-48DD-B17E-00183E63D8A5 is the IdentifyingNumber set in the Product.wxs file on the
    <Product Id="*" ...>
    element. I replaced * with 88705C51-3B43-48DD-B17E-00183E63D8A5:

    <Product Id="88705C51-3B43-48DD-B17E-00183E63D8A5" ...>


    Is this the correct way to do this?

    I don't see how else you can automatically install and un-install the product through the installer, arbitrarily many times. We HAVE to do this as part of our Continuous Delivery process.
    Posted 05 Nov, 2019 13:52:30 Top
    Andrei Smolin


    Add-in Express team


    Posts: 18823
    Joined: 2006-05-11
    Hello John,

    An installer of an add-in cannot be non-silent. This is because installing may require you to uninstall the previous add-in version: this must be non-silent because you need to inform the user that the add-in will be installed only after the host application is closed (this unlocks the files to be replaced with the new add-in version).

    Thus the setup project that Add-in Express creates is non-silent and this cannot be changed.

    The 'silent installation' topic was raised a zillion of times here and in our mail flow. You cannot replace files locked by the Office application loading your add-in until you close the Office application. Should the installer be silent, the user won't know that the host app should be closed and the new add-in version would never be installed.


    Andrei Smolin
    Add-in Express Team Leader
    Posted 06 Nov, 2019 06:16:14 Top
    John Zabroski




    Posts: 12
    Joined: 2019-08-29
    Hi Andrei,

    My deploy process closes all Excel workbooks. I'm not worried about Office forcibly closing as part of the install.

    I see your guidance as a false dichotomy, and I hope people reading my message have learned a trick or two.

    For what it's worth, my "PRO TIP" is to use Octopus Deploy "Run - Windows Installer" step template to install this. The downside is Octopus Deploy charges per deployment target, so if you're planning to install your plug-in to thousands of machines, you may just want to look at the PowerShell script that implements this Step Template.

    If I'm the first person in a zillion tries to get this to work, then I'm flattered. :)

    John
    Posted 06 Nov, 2019 15:42:35 Top