how to pass command line properties to setup.exe - msbuild

I want to pass parameters to msi when calling setup.exe as following :
setup.exe /l* log.txt EXEPATH="C:\Program Files (x86)\MySetup\MyApplication.exe"
I have the following msbuild file :
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<exeD Condition="'$(EXEPATH)'!=''">$(EXEPATH.substring(0,$([MSBuild]::Add($(EXEPATH.lastIndexOf("\")),1))))</exeD>
<exeFile Condition="'$(EXEPATH)'!=''">$(EXEPATH.substring($([MSBuild]::Add($(EXEPATH.lastIndexOf("\")),1))))</exeFile>
</PropertyGroup>
<ItemGroup>
<BootstrapperFile Include="Microsoft.Windows.Installer.4.5" >
<ProductName>Windows Installer 4.5</ProductName>
</BootstrapperFile>
</ItemGroup>
<Target Name="Bootstrapper">
<Message Text="$(exeD)"/>
<Message Text="$(exeFile)"/>
<Message Text="$(EXEPATH)"/>
<Exec Command="msiexec /i MySetup.msi /L log2.txt EXEDIR="$(exeD)" EXEFILENAME="$(exeFile)"" Condition="'$(EXEPATH)'!=''" />
</Target>
</Project>
As you can see I calculate two variables exeFile and exeD which I'll use in the Exec command which are supposed to be passed then to MSI file which wix file is :
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="MySetup" Language="1033" Version="1.0.0.0" Manufacturer="Sofiane" UpgradeCode="c151e7ab-b83a-445f-93b2-2ab7122ea34b">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Property Id="EXEDIR" Secure="yes" Value="{}"/>
<Property Id="EXEFILENAME" Secure="yes" Value="{}"/>
<Feature Id="ProductFeature" Title="MySetup" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Binary Id="InstallTools" SourceFile="$(var.SolutionDir)InstallTools\bin\$(var.Configuration)\InstallTools.dll"/>
<Binary Id="NotepadPlus" SourceFile="C:\Program Files (x86)\Notepad++\notepad++.exe"/>
<!--<CustomAction Id="OpenExe" BinaryKey="InstallTools" DllEntry="OpenExeUrl" Execute="immediate" Impersonate="yes" Return="check" />-->
<CustomAction Id="OpenExe" Return="ignore" Directory="exeDirectory" ExeCommand=""[EXEDIR]\[EXEFILENAME]"" Impersonate="yes" Execute="deferred"/>
<InstallExecuteSequence>
<Custom Action="OpenExe" Before='InstallFinalize'/>
</InstallExecuteSequence>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="MySetup" />
</Directory>
<Directory Id="exeDirectory" FileSource="#(EXEDIR)" />
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Component Id="myAppFile">
<File Source="$(var.MyApplication.TargetPath)" />
</Component>
</DirectoryRef>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<ComponentRef Id="myAppFile" />
<!-- </Component> -->
</ComponentGroup>
</Fragment>
</Wix>
What is strange is that when I test using, it works fine and the exe file is opened.
MSBuild.exe bootstrapper.msbuild /p:EXEPATH="C:\Program Files (x86)\MySetup\MyApplication.exe"
The issue is that when I launch the setup.exe with the following command
setup.exe /l* log.txt EXEPATH="C:\Program Files (x86)\MySetup\MyApplication.exe"
The EXEPATH parameter seems not be used or I don't know why ?
Any advice please ?

I resolve this issue by passing EXEPATH to MSI file and a custom action who will calculate EXEDIR and EXEFILENAME.
Here is the custom action :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Deployment.WindowsInstaller;
using System.Diagnostics;
namespace InstallTools
{
public class CustomActions
{
[CustomAction]
public static ActionResult OpenExeUrl(Session session)
{
try
{
session.Log("Inside custom action");
var expath = session["EXEPATH"];
session.Log("EXEPATH ==> " + expath);
var exedir =expath.Substring(0, expath.LastIndexOf("\\")+1);
session.Log("exedir ==> " + exedir);
session["EXEDIR"] = exedir;
var exefile = expath.Substring(expath.LastIndexOf("\\")+1);
session.Log("exefile ==> " + exefile);
session["EXEFILENAME"] = exefile;
}
catch (Exception e)
{
var errorMessage = "Cannot open exe file ! Error message: " + e.Message;
session.Log(errorMessage);
}
return ActionResult.Success;
}
}
}
The Wix file :
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="MySetup" Language="1033" Version="1.0.0.0" Manufacturer="Sofiane" UpgradeCode="c151e7ab-b83a-445f-93b2-2ab7122ea34b">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Property Id="EXEPATH" Secure="yes"/>
<Feature Id="ProductFeature" Title="MySetup" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Binary Id="InstallTools" SourceFile="$(var.SolutionDir)InstallTools\bin\$(var.Configuration)\InstallTools.CA.dll"/>
<CustomAction Id="SetupProps" BinaryKey="InstallTools" DllEntry="OpenExeUrl" Execute="immediate" Impersonate="yes" Return="check" />
<CustomAction Id="OpenExe" Return="ignore" Directory="exeDirectory" ExeCommand=""[EXEDIR]\[EXEFILENAME]"" Impersonate="yes" Execute="deferred" />
<InstallExecuteSequence>
<Custom Action="SetupProps" Before="OpenExe"/>
<Custom Action="OpenExe" Before="InstallFinalize"/>
</InstallExecuteSequence>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="MySetup" />
</Directory>
<Directory Id="exeDirectory" FileSource="#(EXEDIR)" />
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Component Id="myAppFile">
<File Source="$(var.MyApplication.TargetPath)" />
</Component>
</DirectoryRef>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<ComponentRef Id="myAppFile" />
</ComponentGroup>
</Fragment>
</Wix>
and the msbuild script :
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<BootstrapperFile Include="Microsoft.Windows.Installer.4.5" >
<ProductName>Windows Installer 4.5</ProductName>
</BootstrapperFile>
</ItemGroup>
<Target Name="Bootstrapper">
<Message Text="EXEPATH = $(EXEPATH)"/>
<Exec Command="msiexec /i MySetup.msi /L log2.txt" Condition="'$(EXEPATH)'!=''" />
</Target>
</Project>

Related

WiX: Register app to autorun when Windows is launches doesn't work

I'm trying to register app to autorun when Windows is launches. I can't understand why it doesn't work?
I'm trying to do that:
<!-- Files.wxs -->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:fw="http://schemas.microsoft.com/wix/FirewallExtension"> <Fragment>
<DirectoryRef Id="INSTALLLOCATION"
FileSource="..\MyApp\bin\Release\">
<Component Id ="ProductComponents"
DiskId="1"
Guid="{482A3E9A-8FCA-44C6-96C5-F7B026DF85C4}">
<File Id="MyApp.exe.config" Name="MyApp.exe.config"/>
<File Id="MyApp.exe" Name="MyApp.exe"/>
<RegistryKey
Root="HKLM"
Key="Software\Microsoft\Windows\CurrentVersion\Run">
<RegistryValue Id="MyApp.exe" Name="MyApp" Value="[INSTALLLOCATION]MyApp.exe" Type="string" />
</RegistryKey>
</Component>
</DirectoryRef>
</Fragment>
</Wix>
<!-- Product.wxs -->
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include Variables.wxi?>
<Product Id="*"
Name="$(var.ProductName)"
Language="1033"
Version="$(var.Version)"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="MY_GUID">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<WixVariable Id="WixUILicenseRtf" Value="eula.rtf" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<MajorUpgrade
AllowDowngrades="no"
DowngradeErrorMessage="New version is already installed."
AllowSameVersionUpgrades="no"
Schedule="afterInstallInitialize"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="MyApp" />
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="MyApp" Level="1">
<ComponentRef Id="ProductComponents" />
</Feature>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION"></Property>
<UIRef Id="WixUI_InstallDir"/>
<CustomAction Id="LaunchApp" Directory="INSTALLLOCATION" ExeCommand="[SystemFolder]cmd.exe /C start MyApp.exe" />
<InstallExecuteSequence>
<Custom Action="LaunchApp" After="InstallFinalize">NOT Installed AND NOT REMOVE</Custom>
</InstallExecuteSequence>
</Product>
</Wix>
I want to achieve auto start myApp.
The most likely issue is that it needs elevation and therefore will be blocked by UAC:
https://blogs.msdn.microsoft.com/uac/2006/08/23/elevations-are-now-blocked-in-the-users-logon-path/
and:
Program needing elevation in Startup registry key (windows 7)
If it's not that, then check that the path in the registry Run key is actually correct (in the 32-bit or 64-bit registry).
Entries in the Run key do not run "when Windows is launched". They start when the user logs on. If you really want something to run when Windows starts you need a service or a Task Scheduler entry that starts when Windows starts.

What is wrong with this 'run executable' Wix xml code?

I am trying to execute my.exe using your.exe. It's not working as expected.
Here is the code snippet:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="my_name" Language="1033" Version="1.11.5164"
Manufacturer="company" UpgradeCode="PUT-GUID-HERE">
<Package Description="Test file in a Product" Comments="Simple test"
InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="simple.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Name="my_folder" Id="MY_FOLDER">
<Component Id="your.EXE" DiskId="1" Guid="*">
<File KeyPath="yes" Id="your.exe" Name="your.exe"
Source="your.exe" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="MainFeature" Title="Main Feature" Level="1">
<ComponentRef Id="your.EXE" />
</Feature>
<CustomAction Id="StartAppOnExit" Property="StartAppOnExit" ExeCommand="[SystemFolder]cmd.exe /C your.exe my.exe " Execute="immediate" Return="asyncNoWait" />
<InstallExecuteSequence>
<Custom Action="StartAppOnExit" After="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
</Product>
</Wix>
The custom action StartAppOnExit can't find your.exe. Try using a Directory attribute instead of a Property attribute:
<CustomAction Id="StartAppOnExit" Directory="MY_FOLDER" ExeCommand="[SystemFolder]cmd.exe /C your.exe my.exe " Execute="immediate" Return="asyncNoWait" />
<InstallExecuteSequence>
<Custom Action="StartAppOnExit" After="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
This should run your.exe passing the argument my.exe.
See also Start application after installation.

Why Wix MSI doesn't include the source files and looks for source files somewhere else?

I have used Wix on and off for almost a year. After a little break and now I am back to wix and need to build a wix Msi again but I found a very strange thing that I haven't met before. After I created the msi file and and copy the msi to somewhere to install. During the installation, it shows an error that it can't find the source files from the folder: current msi location\EasyLobby\Cogito. I was wondering why it tried to find the source files from that location. I then found that from the project during the compilation, it always creates \EasyLobby\Cogito under the bin\Debug folder. So if I run the msi right from the ...bin\Debug, it runs OK because the \EasyLobby\Cogito folder is there. \
It seems so strange. The msi file should include all the source files and shouldn't look for source files somewhere else. Here is the product.wxs file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="SetupCogito" Language="1033" Version="2.0.0.0" Manufacturer="Microsoft" UpgradeCode="96cb03c9-6a03-4344-b816-20a0bb9e5df0">
<Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id="1" Cabinet="Server.cab" EmbedCab="yes" />
<!--<MediaTemplate />-->
<Feature Id="ProductFeature" Title="SetupCogito" Level="1">
<ComponentGroupRef Id="ComponentGroup"/>
<ComponentRef Id="EasyLobbyCogitoShortcut" />
</Feature>
<WixVariable Id="WixUILicenseRtf" Value="Files\LicenseAgmt.rtf"/>
<UIRef Id="CogitoUI_Installdir" />
<Property Id="WIXUI_INSTALLDIR" Value="COGITOFOLDER" />
<Binary Id="banner_bmp" SourceFile="Files\Banner.bmp"/>
<Property Id ="PIDTemplate" >
<![CDATA[&&&-&&&&&&-&&&&-&&&&]]>
</Property>
<Icon Id="ELCogitoConfig.exe" SourceFile="..\CogitoIntegration\ELCogitoConfig.exe" />
</Product>
<Fragment>
<Binary Id="CustomActions"
SourceFile="..\CustomActions\bin\Debug\CustomActions.CA.dll" />
<CustomAction Id="IsValidKeyCode"
BinaryKey="CustomActions"
DllEntry="IsValidKeyCode"
Execute="immediate"
Return="check" />
<InstallExecuteSequence>
<Custom Action="IsValidKeyCode"
Before='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="EasyLobby" >
<Directory Id="COGITOFOLDER" Name="Cogito"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="EasyLobby Cogito" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="COGITOFOLDER">
<Component Id="EasyLobbyCogitoShortcut" Guid="{BFE6EB30-0F71-4F92-8D93-84B4EBF41F0E}" >
<File Id="Easy" Source="$(var.SourceDir)\ELCogitoConfig.exe" />
<Shortcut Id="ApplicationStartMenuShortcut" Name="Cogito Configuration" Directory="ApplicationProgramsFolder"
WorkingDirectory='INSTALLDIR' Icon="ELCogitoConfig.exe" IconIndex="0" Advertise="yes"/>
</Component>
</DirectoryRef>
And this is the config for heat in project file:
<Target Name="BeforeBuild">
<PropertyGroup>
<DefineConstants>SourceDir= C:\Development\SetupCogito\CogitoIntegration;</DefineConstants>
<LinkerBaseInputPaths>..\CogitoIntegration\</LinkerBaseInputPaths>
</PropertyGroup>
<HeatDirectory OutputFile="CogitoSetup.wxs" Directory="..\CogitoIntegration" PreprocessorVariable="var.SourceDir" DirectoryRefId="COGITOFOLDER" ComponentGroupName="ComponentGroup" SuppressCom="true" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" AutoGenerateGuids="false" GenerateGuidsNow="true" ToolPath="$(WixToolPath)" />
This line here is your problem:
<Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
Change Compressed=no to Compressed=yes and it will include all the source files in the finished MSI. If you don't compress it, the finished files are not included in the MSI and you get an error if it can't find them at runtime.
See Package reference.

Checking for .NET installed in WiX installer? Where to place the condition?

I need to check for .NET version 4.5 installed before proceeding with my installation. This is my .wxs file. I've placed the propertyref and condition under the tag. Why is this check is not working?
Even if .NET 4.5 is not present on the target system, the installation goes ahead anyway.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="SolidFire Hardware Provider"
Language="1033"
Version="1.0.0.0"
Manufacturer="SolidFire"
UpgradeCode="0c60967f-f184-4b8b-a96a-b1caa4a8879e">
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine" />
<!--Media Id='2' Cabinet='provider.cab' EmbedCab='yes'/-->
<PropertyRef Id="NETFRAMEWORK45"/>
<Condition Message="This application requires .NET Framework 4.5. Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR NETFRAMEWORK45]]>
</Condition>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab='yes'/>
<Feature Id="ProductFeature" Title="InstallProvider" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<!-- IRef Id="WixUI_Minimal"/-->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" ></Property>
<!--Property WixUIDialogBmp = "logo.bmp"></Property-->
<UIRef Id="WixUI_InstallDir"/>
<InstallExecuteSequence>
<Custom Action="RunInstallScript" After="InstallFiles" >NOT Installed</Custom>
</InstallExecuteSequence>
<InstallExecuteSequence>
<Custom Action='BeforeUninstall' Before='RemoveFiles'>REMOVE="ALL"</Custom>
</InstallExecuteSequence>
<CustomAction Id="RunInstallScript"
ExeCommand="cmd /c install-solidfireprovider.cmd"
Directory="INSTALLFOLDER"
Execute="deferred"
Return="check"/>
<CustomAction Id="BeforeUninstall"
ExeCommand="cmd /c uninstall-solidfireprovider.cmd"
Directory="INSTALLFOLDER"
Execute="deferred"
Return="check"/>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="solidfireinstall" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="ProductComponent">
<!-- TODO: Insert files, registry keys, and other resources here. -->
<File Id="restinterfacedll.dll"
Source="..\vssprovider\x64\$(var.build)\RESTInterfacedll.dll"></File>
</Component>
<Component Id="vssdll">
<File Id="vsssolidfireprovider.dll"
Source="..\vssprovider\x64\$(var.build)\vsssolidfireprovider.dll"></File>
</Component>
<Component Id="installscript">
<File Id="installscript"
Source="install-solidfireprovider.cmd"></File>
</Component>
<Component Id="uninstallscript">
<File Id="uninstallscript"
Source="uninstall-solidfireprovider.cmd"></File>
</Component>
<Component Id="registerprovider">
<File Id="registerprovider"
Source="register_app.vbs"></File>
</Component>
<Component Id="vshadow">
<File Id="vshadow"
Source="vshadow.exe"></File>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
That looks OK so you probably also need to:
"Add the -ext command line parameter when calling light.exe to include the WixNetfxExtension in the MSI linking process."

wix, install files and run bat file

I have problem using wix to build msi installer which will install some bat file and run it. I found some example on the internet, but i was not able to make it work :/ here is my wix source file
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="44A8F987-6B89-422B-B41F-1364AE1EF0D5" Name="my_name" Language="1033" Version="1.11.5164" Manufacturer="company" UpgradeCode="BD8652F4-1C1A-4825-9799-7DFB499B9F12">
<Package Description="Test file in a Product" Comments="Simple test" InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="simple.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Name="my_folder" Id="MY_FOLDER">
<Component Id="CONFIGURE.BAT" DiskId="1" Guid="041ED78B-3D42-4EBD-8DAE-29D94DEFFC20">
<File KeyPath="yes" Id="file_configure.bat" Name="configure.bat" Source="C:\Documents and Settings\root\Desktop\some_path\configure.bat" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="MainFeature" Title="Main Feature" Level="1">
<ComponentRef Id="CONFIGURE.BAT" />
</Feature>
<UI />
<UIRef Id="WixUI_Minimal" />
<CustomAction Id="BatchCmd" Property="BatchRun" Value=""[#file_configure.bat]"" Execute="immediate">
</CustomAction>
<CustomAction Id="BatchRun" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="yes">
</CustomAction>
<InstallExecuteSequence>
<Custom Action="BatchCmd" Before="BatchRun">NOT Installed</Custom>
<Custom Action="BatchRun" After="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence>
</Product>
</Wix>
Configure.bat file is installed correctly, but it won't run during install. Plz help