[wix-users] Custom Action to Create and Install a File?

Russell Haley russ.haley at gmail.com
Sat Feb 22 12:48:30 PST 2020


On Sat, Feb 22, 2020 at 12:50 AM Edwin Castro <egcastr at gmail.com> wrote:

> SetProperty is a WiX specific thing. Think of it as syntax sugar. It
> generates a custom action that sets a property. The default custom action
> name is Set<PropertyName>. You can explicitly set the custom action name
> with the Action attribute.
>
> https://wixtoolset.org/documentation/manual/v3/xsd/wix/setproperty.html
>
> Honestly, I thought I had initially made the mistake so I didn't want to
> draw attention to it. ;-p
>
> --
> Edwin G. Castro
>
>
> On Fri, Feb 21, 2020, 23:05 Russell Haley <russ.haley at gmail.com> wrote:
>
>>
>>
>> On Thu, Feb 20, 2020 at 11:57 PM Edwin Castro <egcastr at gmail.com> wrote:
>>
>>> On Thu, Feb 20, 2020 at 10:17 PM Russell Haley <russ.haley at gmail.com>
>>> wrote:
>>>
>>>> The Action executes, but I am not getting any values in the deferred
>>>> CustomAction? This is confirmed in my log files:
>>>> ...
>>>> Action 21:47:33: Configure.LuaRocks.
>>>> MSI (s) (A4:1C) [21:47:33:332]: Executing op:
>>>> CustomActionSchedule(Action=Configure.LuaRocks,ActionType=1025,Source=BinaryData,Target=ConfigureLuaRocks,CustomActionData=LuaRocksConfigPath=;LuaRocksRootPath=;LuaRootPath=;ToolsPath=)
>>>> MSI (s) (A4:A8) [21:47:33:335]: Invoking remote custom action. DLL:
>>>> C:\WINDOWS\Installer\MSI2C78.tmp, Entrypoint: ConfigureLuaRocks
>>>> MSI (s) (A4:6C) [21:47:33:335]: Generating random cookie.
>>>> MSI (s) (A4:6C) [21:47:33:347]: Created Custom Action Server with PID
>>>> 18240 (0x4740).
>>>> MSI (s) (A4:8C) [21:47:33:380]: Running as a service.
>>>> MSI (s) (A4:8C) [21:47:33:384]: Hello, I'm your 32bit Impersonated
>>>> custom action server.
>>>> SFXCA: Extracting custom action to temporary directory:
>>>> C:\Users\russh\AppData\Local\Temp\MSI2C78.tmp-\
>>>> SFXCA: Binding to CLR version v4.0.30319
>>>> Calling custom action
>>>> Winlua.Installer.CustomAction!Winlua.Installer.CustomAction.CustomActions.ConfigureLuaRocks
>>>> ...
>>>> (Full log here: https://pastebin.com/ycJfigrr - It takes a while to
>>>> load!)
>>>>
>>>
>>> Here is the relative order of when those properties got set
>>>
>>> MSI (s) (A4:1C) [21:47:25:910]: PROPERTY CHANGE: Adding
>>> Configure.LuaRocks property. Its value is
>>> 'LuaRocksConfigPath=;LuaRocksRootPath=;LuaRootPath=;ToolsPath='.
>>> MSI (s) (A4:1C) [21:47:25:911]: PROPERTY CHANGE: Adding
>>> LuaRocksConfigPath property. Its value is 'C:\Program Files
>>> (x86)\WinLua\LuaRocks\\config-[LuaVersion2].lua'.
>>> MSI (s) (A4:1C) [21:47:25:913]: PROPERTY CHANGE: Adding LuaRocksRootPath
>>> property. Its value is 'C:\Program Files (x86)\WinLua\LuaRocks\'.
>>> MSI (s) (A4:1C) [21:47:25:914]: PROPERTY CHANGE: Adding LuaRootPath
>>> property. Its value is 'C:\Program Files (x86)\WinLua\Lua\'.
>>> MSI (s) (A4:1C) [21:47:25:915]: PROPERTY CHANGE: Adding ToolsPath
>>> property. Its value is 'C:\Program Files (x86)\WinLua\LLVM-MinGW\'.
>>>
>>> Notably, Configure.LuaRocks was set *before* the properties it depended
>>> on. The Before attributes were set to Configure.LuaRocks which is the
>>> deferred custom action. The custom action that sets the property is called
>>> SetConfigure.LuaRocks.
>>>
>>> Also, LuaRocksConfigFileName must be set with SetProperty (not Property
>>> like I did initially) and it must be set before LuaRocksConfigPath.
>>>
>>> Something like this
>>>
>>> <SetProperty Id="LuaRocksConfigFileName"
>>> Value="config-[LuaVersion2].lua" Before="SetLuaRocksConfigPath"
>>> Sequence="execute" />
>>>
>>> <SetProperty Id="LuaRocksRootPath" Value="[LUAROCKS_INSTALLLOCATION]"
>>> Before="SetLuaRocksConfigPath" Sequence="execute" />
>>>
>>> <SetProperty Id="LuaRocksConfigPath" Value="[LuaRocksRootPath]\[LuaRocksConfigFileName]"
>>> Before="SetConfigure.LuaRocks" Sequence="execute" />
>>>
>>> <SetProperty Id="LuaRootPath" Value="[LUA_INSTALLLOCATION]"
>>> Before="SetConfigure.LuaRocks" Sequence="execute" />
>>>
>>> <SetProperty Id="ToolsPath" Value="[LLVMMINGW_INSTALLLOCATION]"
>>> Before="SetConfigure.LuaRocks" Sequence="execute" />
>>>
>>> <SetProperty Id="Configure.LuaRocks" Value="LuaRocksConfigPath=[
>>> LuaRocksConfigPath];LuaRocksRootPath=[LuaRocksRootPath];LuaRootPath=
>>> [LuaRootPath];ToolsPath=[ToolsPath]" Before="Configure.LuaRocks"
>>> Sequence="execute" />
>>>
>>
>> Oh, I'm sorry. I thought the Set... stuff was a typo! How am I completely
>> not seeing that in the documentation? (I'll find it!)
>> https://docs.microsoft.com/en-us/windows/win32/msi/custom-actions
>>
>> Ha ha. I've never had someone so politely tell me that I mangled their
>> code. Thanks Edwin.
>>
>> To the Bat Cave!
>> Russ
>>
> Now we're cooking with burn! (tee hee). Here's where I landed (I realize
the condition on the tools path may very well be redundant):

    <!-- Include Features and Directories Fragment -->
    <DirectoryRef Id="LUA_INSTALLLOCATION" />
    <DirectoryRef Id="LUAROCKS_INSTALLLOCATION" />
    <DirectoryRef Id="LIBRESSL_INSTALLLOCATION" />
    <DirectoryRef Id="JAMPLUS_INSTALLLOCATION" />
    <DirectoryRef Id="LLVMMINGW_INSTALLLOCATION" />

    <!--Properties for the LuaRocks configuraiton file that we generate
with Configure.LuaRocks custom Action-->
    <SetProperty Id="LuaRocksConfigFileName"
Value="config-$(var.LuaVersion).lua" Before="SetLuaRocksConfigPath"
Sequence="execute" />
    <SetProperty Id="LuaRocksRootPath" Value="[LUAROCKS_INSTALLLOCATION]"
Before="SetLuaRocksConfigPath" Sequence="execute" />
    <SetProperty Id="LuaRocksConfigPath"
Value="[LuaRocksRootPath]\[LuaRocksConfigFileName]"
Before="SetConfigure.LuaRocks" Sequence="execute" />
    <SetProperty Id="LuaRootPath" Value="[LUA_INSTALLLOCATION]"
Before="SetConfigure.LuaRocks" Sequence="execute" />

    <!--Don't set this property if the LLVM compiler is not being
installed-->
    <SetProperty Id="ToolsPath" Value="[LLVMMINGW_INSTALLLOCATION]"
Before="SetConfigure.LuaRocks" Sequence="execute">
      <![CDATA[Installed OR (&LLVM-MinGW=3) AND NOT(!LLVM-MinGW=3)]]>
    </SetProperty>
    <SetProperty Id="Configure.LuaRocks"
Value="LuaRocksConfigPath=[LuaRocksConfigPath];LuaRocksRootPath=[LuaRocksRootPath];LuaRootPath=[LuaRootPath];ToolsPath=[ToolsPath]"
Before="Configure.LuaRocks" Sequence="execute" />

    <!-- The deferred custom action -->
    <Binary Id='WinLua.Installer.CustomAction'
SourceFile='..\Winlua.Installer.CustomAction\bin\Release\Winlua.Installer.CustomAction.CA.dll'/>
    <CustomAction Id="Configure.LuaRocks"
BinaryKey="WinLua.Installer.CustomAction" DllEntry="ConfigureLuaRocks"
Execute="deferred" Return="check" />

      <!-- Schedule the deferred custom action between InstallInitialize
and InstallFinalize -->
      <InstallExecuteSequence>
        <!-- Only run this when the LuaRocks feature is installed-->
        <Custom Action="Configure.LuaRocks" After="InstallFiles">
          <![CDATA[Installed OR (&LuaRocks=3) AND NOT(!LuaRocks=3)]]>
        </Custom>
    </InstallExecuteSequence>


I'm getting a permissions error in the deferred action when writing the
file.(File here https://pastebin.com/iMFe0Yay) Here is the error:

Calling custom action
Winlua.Installer.CustomAction!Winlua.Installer.CustomAction.CustomActions.ConfigureLuaRocks
***WinLua: Begin CustomAction1
WinLua: Found LuaRocks
WinLua: LuaRocks installed in C:\Program Files (x86)\WinLua\LuaRocks\
WinLua: lua_exe installed in C:\Program Files (x86)\WinLua\Lua\
WinLua: Installed LLVM (aparently)
WinLua: Begin Write
WinLua: Found Tools path
WinLua: Format external_*
Exception thrown by custom action:
System.Reflection.TargetInvocationException: Exception has been thrown by
the target of an invocation. ---> System.UnauthorizedAccessException:
Access to the path 'C:\Program Files (x86)\WinLua\LuaRocks\config-5.3.lua'
is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess
access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize,
FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean
bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess
access, FileShare share, Int32 bufferSize, FileOptions options, String
msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamWriter.CreateFile(String path, Boolean append,
Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding
encoding, Int32 bufferSize, Boolean checkHost)
   at System.IO.File.InternalWriteAllText(String path, String contents,
Encoding encoding, Boolean checkHost)
   at System.IO.File.WriteAllText(String path, String contents)
   at CallSite.Target(Closure , CallSite , Type , Object , String )
   at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3(CallSite site,
T0 arg0, T1 arg1, T2 arg2)
   at Winlua.Installer.CustomAction.CustomActions.WriteConfigFile(Session
session, LuaGlobal g)
   at Winlua.Installer.CustomAction.CustomActions.ConfigureLuaRocks(Session
session)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object
arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj,
Object parameters, Object arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
invokeAttr, Binder binder, Object parameters, CultureInfo culture)
   at
Microsoft.Deployment.WindowsInstaller.CustomActionProxy.InvokeCustomAction(Int32
sessionHandle, String entryPoint, IntPtr remotingDelegatePtr)
CustomAction Configure.LuaRocks returned actual error code 1603 (note this
may not be 100% accurate if translation happened inside sandbox)
Action ended 0:01:28: InstallFinalize. Return value 3.

All sources are here:
https://github.com/WinLua/WinLua-Source-Code/tree/master/WinLua-Release3/WinLua-Installer

Russ

>
>>> --
>>> Edwin G. Castro
>>>
>>>



More information about the wix-users mailing list