0

I've tested and ran my PS1 scripts and they ran find without any problem. So I tried to integrate them into my WiX installer but they just fail but the stupid installer never give back anything meaningful on why it failed...

I have these in my WiX wxs file:

<Property Id="InstallPlugin" Value="&quot;Powershell.exe -File [#InstallPS1]&quot;" />
<CustomAction Id="InstallPlugin" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>

<Property Id="UninstallPlugin" Value="&quot;Powershell.exe -File [#UninstallPS1]&quot;" />
<CustomAction Id="UninstallPlugin" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>

<InstallExecuteSequence>
  <Custom Action="InstallPlugin" Before="InstallFinalize">NOT Installed</Custom>
  <Custom Action="UninstallPlugin" After="InstallInitialize">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
</InstallExecuteSequence>

I captured the install log, I can see the script being called and then failed with code 1603, which doesn't really mean anything...

MSI (s) (F0:B0) [11:15:45:969]: Running as a service.
MSI (s) (F0:B0) [11:15:45:972]: Hello, I'm your 32bit Elevated Non-remapped custom action server.
WixQuietExec:  Entering WixQuietExec in C:\Windows\Installer\MSI19C1.tmp, version 3.11.1701.0
WixQuietExec:  "Powershell.exe -File C:\Program Files (x86)\Blah\install.ps1"
WixQuietExec:  Error 0x80070002: Command failed to execute.
WixQuietExec:  Error 0x80070002: QuietExec Failed
WixQuietExec:  Error 0x80070002: Failed in ExecCommon method
CustomAction InstallPlugin returned actual error code 1603 but will be translated to success due to continue marking

I've tried various combinations of the CustomAction attributes but that didn't help at all. I would love to use Return="check" but that would prevent my installer to finish (my installer has no problem installing everything else, there is no errors, is only the ps1 script somehow blocking).

If I navigate to my installed folder, say, C:\Program Files (x86)\Blah and manually run my script, .\install.ps1, it ran and behave as expected.

Can any WiX experts give me some tips of troubleshooting this? Googling around didn't help...

PS: In the install.ps1 it would launch a elevated powershell session (but it shouldn't matter since the person running the installer must have admin rights to begin with), I'm not sure if that's causing the error, and if yes, then how can I workaround my script launching another script?

Edit:

The script I'm trying to run in question is posted here in the superuser forum. Essentially, I'm just going through the Windows Registry trying to find the Exchange Server installed and grab the built-in EMS script and load it.

codenamezero
  • 2,724
  • 29
  • 64
  • 0x80070002 - drop high word, which leaves you with 2 - file not found. – Bill_Stewart Jul 25 '17 at 17:00
  • @Bill_Stewart how can I ensure the execution sequence so that my `Custom Action` is run after the install? The only reason it can't find the file, is that it tries to execute before the installer put the files there... I thought `After="InstallFinalize"` would ensure the files are in their destination folder. If i look at the actual path, my script is there, I can copy paste the command and run the script. So I'm not sure how it could be `File Not Found`. – codenamezero Jul 25 '17 at 17:21
  • I am not familiar with WiX, so I'm not the right person to answer your question. I'm just saying that's what the error means. – Bill_Stewart Jul 25 '17 at 17:33

3 Answers3

2

The WiX quiet execute CA requires the powershell.exe to be fully qualified and wrapped in quote.

"[SystemFolder]WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -File "[#fileKey]"

or something like that. But honestly, I'd probably do this all in c# / DTF or use c# / DTF to create a powershell pipeline and invoke it that way. Much more control over the invocation, error handling, logging and on so on.

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
  • Makes no difference, it gives exactly the same error. `WixQuietExec: "C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File 'C:\Program Files (x86)\Blah\test.ps1'"` Running that command manually would work without error, i had `echo "hello world"` in my `test.ps1` script there. – codenamezero Jul 25 '17 at 18:45
  • your missing " after .exe. I know it's wierd but the full path to the EXE has to be "" args come after. – Christopher Painter Jul 25 '17 at 21:48
  • I did tried that, if you look at my answer, i am using `"powershell.exe"`. I also tried both ways and it doesn't need to be a fully qualified path. Something is fishy about it that doesn't work with `-File` but able to trigger the call when using `-Command`, seems like a bug of WiX imo... – codenamezero Jul 26 '17 at 13:58
  • So unfortunately MSI AppSearch can't recurse subkeys like that. But you can do it with a custom action scheduled in the immediate execution context to apply those business rules and set an MSI property with the directory and then pass that off to AppSearch to use in a file search or you could just continue the logic all the way through and set the property with the full path to the ps1. But what is it doing after that? Generally "self registration" is considered an MSI antipattern and I'm tryingto decompose the script and translate it into MSI concepts to eliminate custom actions. – Christopher Painter Jul 26 '17 at 15:45
  • The goal of all this, is to register my `Transport Agent plugin` with the Exchange Server, and in order to do that, I need to load the `Exchange Management Shell`, which is what my powershell script does, it finds the `RemoteExchange.ps1`, then loads it, from there I run my other scripts to register and enable my plugin. Calling my scripts manually all worked, it is only calling it from the MSI that is giving me tons of trouble. – codenamezero Jul 26 '17 at 16:14
  • Perhaps you can take a look at this one instead? https://stackoverflow.com/questions/45313813/how-to-start-powershell-in-wix-with-proper-access-to-windows-registry – codenamezero Jul 26 '17 at 16:17
  • "[SystemFolder]WindowsPowerShell\v1.0\powershell.exe" works for me. – Mahesh Dec 05 '19 at 10:06
0

After a couple of hours of hammering, the only way I got it to work is to use -Command instead of -File, and I also need to use SetProperty instead of Property.

For some reason, <Property> and -File isn't working:

<Property Id="InstallPlugin" Value="&quot;powershell.exe&quot; -NoProfile -ExecutionPolicy Bypass -File '[#TestPS1]'&quot;" />

I had to force myself to use <SetProperty>, Before, and -Command in order to trigger the execution.

<SetProperty Id="InstallPlugin"
     Before="InstallPlugin"
     Sequence="execute"
     Value ="&quot;powershell.exe&quot; -Command &quot;cd '[INSTALLFOLDER]'; &amp; '[#InstallPS1]' ; exit $$($Error.Count)&quot;" />

<CustomAction Id="InstallPlugin" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="check" Impersonate="no" />

The good news is that this works, but the bad, unrelated news, is that the powershell launched by the installer doesn't seems to have access to the Windows Registry... I will open a different SO question for that.

codenamezero
  • 2,724
  • 29
  • 64
-2

I think this is more of an MSI question. I'd suggest using:

msiexec 'path/file' /l*v logfile.txt

This will capture verbose logging from the msi. The only CLI output I've gotten from msiexec in the past has been to warn me the package is already running, nothing about what the executable is actually doing.

Maximilian Burszley
  • 18,243
  • 4
  • 34
  • 63