Trying to get a wix installer to kill a process, from what I have found online it looks like this is the way to go:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="WindowsFolder" Name="WINDOWS"/>
<Property Id="QtExecCmdLine" Value='"[WindowsFolder]System32\taskkill.exe" /F /IM Foo.exe'/>
<CustomAction Id="KillTaskProcess" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="immediate" Return="ignore"/>
The problem I have is building the project will throw the following error complaining about the windows property:
The 'QtExecCmdLine' Property contains '[WindowsFolder]' in its value which is an illegal reference to another property. If this value is a string literal, not a property reference, please ignore this warning. To set a property with the value of another property, use a CustomAction with Property and Value attributes.
I have tried [#WindowsFolder] instead, it removes the error but does not solve the issue.
Using the full address (C:\Windows\System32\taskkill.exe) instead for the value does work but I would like to avoid that.
I don't think you can reference a directory in the way that you are (e.g. "[WindowsFolder]"). This type of annotation is used to reference the values of properties.
WindowsInstaller does already provide a Public property which represents the System Folder on any given system.
You can use [SystemFolder] on 32 bit machines to get c:\Windows\System32 (note on 64 bit machines this will give you c:\Windows\SysWow64).
Therefore, on 64 bit machines you can use [System64Folder] which will give you c:\Windows\System32
Your code would then look like
<Property Id="QtExecCmdLine" Value='"[SystemFolder]taskkill.exe" /F /IM Foo.exe'/>
Or
<Property Id="QtExecCmdLine" Value='"[System64Folder]taskkill.exe" /F /IM Foo.exe'/>
I perform a similar operation in an installation package which supports both 32 & 64 bit machines. This complicates matters slightly.
To get around this I would try the following with your code:
<Property Id="TASKKILLFILEPATH"/>
<Property Id="QtExecCmdLine" Value='"[TASKKILLFILEPATH]" /F /IM Foo.exe'/>
Then, add a custom action to properly set the task kill file path
<CustomAction Id='SetTASKKILLFILEPATH32' Property='TASKKILLFILEPATH' Value='[SystemFolder]\taskkill.exe' Return='check' />
<CustomAction Id='SetTASKKILLFILEPATH64' Property='TASKKILLFILEPATH' Value='[System64Folder]\taskkill.exe' Return='check' />
In InstallExecuteSequence you can run the appropriate custom action based on the system type:
<InstallExecuteSequence>
<Custom Action='SetTASKKILLFILEPATH64' After='AppSearch'>VersionNT64</Custom>
<Custom Action='SetTASKKILLFILEPATH32' After='AppSearch'>Not VersionNT64</Custom>
</InstallExecuteSequence>
BTW VersionNT64 is yet another WindowsInstaller provided property.
This might be a bit overkill and I hope there is an easier way of doing this that someone else might share, but I know this to be a working solution. Hope this, at least, leads you in the right direction.
Why not use a VBScript to kill the process? Here is a standard script:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = 'Notepad.exe'")
For Each objProcess in colProcessList
objProcess.Terminate()
Next