Wix:CustomAction failure in action immediate or deferred either - batch-file

Environment: Windows 7 x64, Wix Toolset 3.10
Hello
I cannot call cmd.exe by Custom Action through Execute attribute "immediate" or "deferred" in either way.
Runtime Error always happen.
I can call vbs command by a Custom Action, but cannot fire .bat file,
What's wrong? I suppose there might be inconsistency between the path of input and output, but I cannot find it.
If I can output the log files with only English, please teach me....
In deferred action, log InstallInitialize, InstallFinalize might suggest me to do something with Orca, but I am not sure what I should do.
Below is detail of my attempt:
Following a sample suggested in https://alexanderst.wordpress.com/2010/10/28/wix-how-to-run-application-with-parameters-from-custom-action/
My definition of a property for cmd.exe below:
<Property Id="CMD">
<DirectorySearch Id="CmdFolder" Path="[SystemFolder]" Depth="1">
<FileSearch Id="CmdExe" Name="cmd.exe" />
</DirectorySearch>
</Property>
My definition of a directory for a batch file below:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="FugaFuga" Name="FugaFuga">
<Directory Id="INSTALLDIR" Name="Hoge 1.0">
<Component Id="FugaFugaLibrary" Guid="MY-UID">
<File Id="test.bat" Name="test.bat" DiskId="1" Source="test.bat" KeyPath="yes" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
My definition of the Publish Event DoAction is below:
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="Next(&N)">
<Publish Event="DoAction" Value="CallCmdTest">1</Publish>
<Publish Event="NewDialog" Value="NextDlg" />
</Control>
test.bat content is below (both of hoge.txt and temp\hoge folder exist)
copy /Y C:\temp\hoge\hoge.txt C:\temp\hoge\hoge%date:~-10,4%%date:~-5,2%%date:~-2,2%.txt
It simply copys the hoge.txt to a hoge{%date% without slash}.txt
I tried Execute="deferred" but Runtime Error happens when the next button is pushed.
<CustomAction Id="CallCmdTest" Property="CMD" Return="check" Execute="deferred" Impersonate="yes" ExeCommand="/c ""[#test.bat]""" />
Its log file (I'm sorry for the japanese characters...)(msiexec /i Main.msi /lv* Main-install.log result:) Error 2762 but return code is 3...
アクション開始 11:04:22: CallCmdTest。
MSI (c) (08:C0) [11:04:22:176]: Note: 1: 2762
DEBUG: Error 2762: Unable to schedule operation. The action must be scheduled between InstallInitialize and InstallFinalize.
このパッケージをインストールしているときに、インストーラーに予期しないエラーが発生しました。このパッケージに問題がある可能性があります。エラー コードは、2762 です。引数: 、、
MSI (c) (08:C0) [12:03:24:486]: 製品: HogeHoge 1.12.0 -- このパッケージをインストールしているときに、インストーラーに予期しないエラーが発生しました。このパッケージに問題がある可能性があります。エ ラー コードは、2762 です。引数: 、、
アクション終了 12:03:24: CallCmdTest。 戻り値 3。
I tried Execute="immediate" but a Runtime Error happens either when the next button is pushed:
<CustomAction Id="CallCmdTest" Property="CMD" Return="check" Execute="immediate" ExeCommand="/c ""[#test.bat]""" />
Its log file (I'm sorry for the japanese characters...)(msiexec /i Main.msi /lv* Main-install.log result:) Error 2762 but return code is 3..
アクション開始 17:13:23: CallCmdTest。
MSI (c) (B8:C4) [17:13:24:034]: Note: 1: 1722 2: CallCmdTest 3: C:\Windows\SysWOW64\cmd.exe 4: /c ""C:\Program Files (x86)\HogeHoge\Hoge 1.0\test.bat""
エラー 1722。この Windows インストーラー パッケージに問題があります。セットアップの一部として実行されるプログラムが正常に完了しませんでした。サポート担当者またはパッケージ開発元に問い合わせてください。アクション CallCmdTest、場所: C:\Windows\SysWOW64\cmd.exe、コマンド: /c ""C:\Program Files (x86)\HogeHoge\Hoge 1.0\test.bat""
MSI (c) (B8:C4) [17:13:25:694]: 製品: HogeHoge 1.12.0 -- エラー 1722。この Windows インストーラー パッケージに問題があります。セットアップの一部として実行されるプログラムが正常に完了しませんでした。サポート担当者またはパッケージ開発元に問い合わせてください。アクション CallCmdTest、場所: C:\Windows\SysWOW64\cmd.exe、コマンド: /c ""C:\Program Files (x86)\HogeHoge\Hoge 1.0\test.bat""
アクション終了 17:13:25: CallCmdTest。 戻り値 3。
DEBUG: Error 2896: Executing action CallCmdTest failed.
このパッケージをインストールしているときに、インストーラーに予期しないエラーが発生しました。このパッケージに問題がある可能性がありま す。エラー コードは、2896 です。引数: CallCmdTest、、
アクション終了 17:13:25: WelcomeDlg。 戻り値 3。
MSI (c) (B8:B8) [17:13:25:716]: Doing action: FatalError
アクション 17:13:25: FatalError。
All files (Main.wxs, Main.wixobj, Main.msi, test.bat) exist in one folder.
All commands of candle, light, msiexec are executed in the same directory.
cd /d %~dp0
candle.exe Main.wxs
light.exe -cultures:ja-jp -ext WixUIExtension -out Main.msi Main.wixobj
msiexec /i Main.msi /lv* Main-install.log

As Gerhard Barnard metioned, using a custom action is probably the right way to do this. It looks like you are trying to trigger your custom action from the UI which
Can't be deferred as it is happening from the UI
Can't have elevation unless the entire installer was launched elevated
Won't be able to access the bat file if you haven't actually installed the product yet.
I would instead rewrite your bat file as a c# or c++ custom action and include that in your installer following the instructions in the link in Gerhard's comment and other SO questions.
Additionally, Custom actions launched from a UI event can't write logs easily to the msi log (or at all?). If you schedule your custom action appropriately you will be able to do informative logging about what your custom action is doing. You can also debug your custom action if necessary. In the past I've shown a message box at the start of the custom action then attached a debugger for debugging.

Related

Remote access to network share per wmic/ps1 : Access is denied

I want to call (execute) a cmd or ps1 script remotely from one Windows 2016 Server 2016 on another. The problem is that script access to a \\network-share is denied.
Reproduce:
(1) a batch or ps1 script with specific Domain-User to \\network-share is successful:
dir \\network-share results in what it should.
(2) try to execute this script from another server via wmic or ps1 with the same user that has access to \\network-share (wmic /node:"node" /user:"domain\usr" /password:"pwd" process call create "cmd.exe /c C:\temp\cmd.bat").
The cmd.bat contains: dir \\network-share or dir \\<UNC-FQDN>\share or dir \\<IP>\share and always gets „Access is denied“ although domain\usr itself has access to the \\network-share.
(3) the identical routine (2) with dir C:\temp runs like expected.
Already tried some registry keys, e.g.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies]
DisableLoopbackCheck
DisableStrictNameChecking
BackConnectionHostNames
LocalAccountTokenFilterPolicy
Maybe one of those is needed on both machines and I did not try every option but to understand what might be the problem here could help I guess.
So, thx & Kind Regards :-)
In the meantime I found two ways to overcome the problem:
a) using Sysinternals PsExec.exe -u domain\user -p pwd -i \\node C:\temp\cmd.bat
b) Create a Scheduled Task on the target machine that can be executed remotely by C:\Windows\System32\schtasks.exe /run /tn "name of the task" /s node /u domain\user /p pwd
Maybe this will help somebody else.

WIX installer: How to create environment variable from vswhere.exe output

I have a window installer XML (WIX) installer.
I use Visual Studio vswhere.exe to find out Visual Studio InstallationPath and InstanceId for further usage in my WIX code, see below:
<SetProperty Id="InstallationPathProf2019"
Value=""[SystemFolder]cmd.exe" /C ""[VS_INSTALLER_DIR_PATH]\vswhere.exe" -products Microsoft.VisualStudio.Product.Professional -property InstallationPath -version [\[]16.0,17.0[\)] > [TempFolder]InstallationPathProf2019.txt" && set /P VS_2019_INSTALLATIONPATH=<[TempFolder]InstallationPathProf2019.txt"
Before="InstallationPathProf2019" Sequence="execute" >NOT REMOVE="ALL"</SetProperty>
<CustomAction Id="InstallationPathProf2019" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Impersonate="no"/>
<SetProperty Id="InstanceIdProf2019"
Value=""[SystemFolder]cmd.exe" /C ""[VS_INSTALLER_DIR_PATH]vswhere.exe" -products Microsoft.VisualStudio.Product.Professional -property InstanceId -version [\[]16.0,17.0[\)] > [TempFolder]InstanceIdProf2019.txt && set /P VS_2019_INSTANCEID=<[TempFolder]InstanceIdProf2019.txt""
Before="InstanceIdProf2019" Sequence="execute" >NOT REMOVE="ALL"</SetProperty>
<CustomAction Id="InstanceIdProf2019" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Impersonate="no"/>
in addition, I use set directory with the value retrieved from vswhere as following:
<SetDirectory Id="APPLICATIONROOTDIRECTORY" Value="[%VS_2019_INSTALLATIONPATH]\Test" Sequence="execute" />
Which doesn't work:
return empty string - MSI (c) (28:F8) [12:15:12:623]: PROPERTY CHANGE: Adding APPLICATIONROOTDIRECTORY property. Its value is '\Test'.
When I use predefined environment variable it work:
<SetDirectory Id="USERPROFILDIR" Value="[%USERPROFILE]\MyTest" Sequence="first" />
I see in log file:
PROPERTY CHANGE: Adding USERPROFILDIR property. Its value is 'C:\Users\donnam\MyTest'.
Why in my case it returns empty string? can't I set a value of environment variable and use it afterwards on my WIX code?
P.S. performing the above in CMD (not through WIX) I see environment variable is created:
set environment from vswhere output
I hope someone can help!
The solution is to use setx to create environment variable instead of set.
More information about setx can be found at:
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/setx

Creating a cmd line shortcut

I am completely new to Windows, as i am an OSX user.
I am having to run a task in the cmd line every day, is there any way i can create a shortcut on my desktop which automates this?
Task example, open cmd, then execute:
atomInstaller npm -view -Xmx8g -Xms3g
Thanks
You could just make a shortcut to cmd.exe and add command line switches:
https://superuser.com/questions/358565/adding-command-line-switches-to-windows-shortcuts
Or you can put commands into a batch file using notepad ( or a better text editor ):
#echo off
atomInstaller npm -view -Xmx8g -Xms3g
save it as npm.bat then double-click it..
You can use shortcutjs.bat:
call shortcutjs.bat -linkfile "%userprofile%\desktop\atominstaller.lnk" -target "C:\atomInstaller.bat" -adminpermissions yes -iconlocation "C:\Windows\System32\compstui.dll,3" -hotkey "Ctrl+Shift+M"
Here's the usage:
shortcutjs.bat -linkfile link -target target [-linkarguments linkarguments] [-description description] [-iconlocation iconlocation] [-hotkey hotkey] [-windowstyle 1|3|7] [-workingdirectory workingdirectory] [-adminpermissions yes|no]
You can add additional parameter with -linkarguments or start location with -workingdirectory

TortoiseSvn - Automatically update multiple external properties

I'm currently working on tortoise svn. In order to be able to automatically tag trunk projects so i need to focus on the external properties. As well i would like to edit them automatically using a batch file.
Until now what i've done is:
Getting the last version of the folder which is pointed by the
external property (in order to be able to tag a specific version and
not the head one)
Edit the external property using command line
My batch file looks like this :
::GETTING THE LAST VERSION NUMBER OF THE SOURCE DIRECTORY
svnversion -c %SRC_PATH_WC% | sed -e 's/[MS]//g' -e 's/^[[:digit:]]*://'>temp.txt
set /p VERSION=<temp.txt
del temp.txt
echo %VERSION%
pause
::CREATING THE SVN:EXTERNAL WITH THE VERSION CHOOSEN
svn propset svn:externals "%DIRECTORY_NAME% -r%VERSION% %SVN_SRC_PATH%" .
pause
Now I would like to be able to set multiple external properties. I think i can't by using the svn propset command but i have no clue on what other command to use and how to use it.
Thank you in advance for your help
I've found my answer on another site.
Here is what i've used :
::CREATE FILE AND WRITE THE SVN:EXTERNALS PROPERTIES
echo %DIRECTORY_NAME1% -r%VERSION1% %SVN_SRC_PATH1% > svn_externals
echo %DIRECTORY_NAME2% -r%VERSION2% %SVN_SRC_PATH2% >> svn_externals
::CREATING THE SVN:EXTERNAL WITH THE VERSION CHOOSEN
svn propset svn:externals -F svn_externals .

Wix: use computername in custom action directory

I want to use the name of the computer where the msi is running in a customaction to execute a batch file that is deployed with the msi file in a directory that is the same as the computername.
For example, after installation of the msi on a machine named: 'MyServer' the directory looks like: C:\program files\MyApp\Config\MyServer\Config.bat
I want to run the Config.bat file after installation, so i came up with custom action
<CustomAction
Id="CONFIGURE"
Directory="INSTALLFOLDER\Config\[COMPUTERNAME]"
ExeCommand="Configure.bat"
Execute="deferred"
Return="ignore" />
<InstallExecuteSequence>
<Custom Action="CONFIGURE"
After="InstallFiles" />
</InstallExecuteSequence>
Now i need the real computername instead of the [COMPUTERNAME].
Or something like this:
<CustomAction
Id="CONF"
Directory="INSTALLFOLDER"
ExeCommand="\Config\[COMPUTERNAME]\Configure.bat"
Execute="deferred"
Return="ignore"
HideTarget="no"
Impersonate="no" />
The above examples looks better, but at installation the log file tells me:
Action: CONF, location: c:\Program Files (x86)\MyApp\, command: \Config\\Configure.bat
So the computername is empty...
+++
Finally thanks to the one Dusan Plavak, the solution is:
<CustomAction
Id="CONF"
Directory="INSTALLFOLDER"
ExeCommand="\Config\[ComputerName]\Configure.bat"
Execute="deferred"
Return="ignore"
HideTarget="no"
Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="CONF"
After="InstallFiles" />
</InstallExecuteSequence>
You should use ComputerName instead of COMPUTERNAME
so for example you can copy ComputerName to COMPUTERNAME name using custom action"
<CustomAction Id="SetMachineName" Property="COMPUTERNAME" Value="[ComputerName]" Execute="immediate"></CustomAction>

Resources