Run custom action exe
I'm trying to run a custom action exe but I'm confused about the Type and Target columns. I need to run my.exe that is located in "C:\Program Files\Sony\ICD-P Series Driver" and pass the following parameter to it "C:\Program Files\Sony\ICD-P Series Driver". Here is what I have in the CustomAction table:
CA_InstallOEMinf 3282 setupcopyoeminf.exe [ICD_P_SERIES_DRIVER]
CA_InstallOEMinf 3282 setupcopyoeminf.exe [ICD_P_SERIES_DRIVER]
0 Comments
[ + ] Show comments
Answers (28)
Please log in to answer
Posted by:
captain_planet
15 years ago
Posted by:
joedown
15 years ago
Posted by:
captain_planet
15 years ago
Yeah, you'll probably want to use a type 50 Custom Action then. You'd have something like:
Action: (name of your ca)
Type: 50 (or may change depending on what execution options you have set)
Source: MyExePath
Target: "C:\Program Files\Sony\ICD-P Series Driver" (This is the parameter)
Then define a property called 'MyExePath' with a value of "C:\Program Files\Sony\ICD-P Series Driver\my.exe"
Try executing it as Immediate, after InstallFinalize.
Action: (name of your ca)
Type: 50 (or may change depending on what execution options you have set)
Source: MyExePath
Target: "C:\Program Files\Sony\ICD-P Series Driver" (This is the parameter)
Then define a property called 'MyExePath' with a value of "C:\Program Files\Sony\ICD-P Series Driver\my.exe"
Try executing it as Immediate, after InstallFinalize.
Posted by:
jmcfadyen
15 years ago
[ICD_P_SERIES_DRIVER]
your target should be this
[#ICD_P_SERIES_DRIVER] the # indicates the full path to a file in the file table. (using its primary key)
try to avoid writing the path as suggested by captain_planet this is not dynamic and if the user changes the installation path it will fail deployment.
Posted by:
captain_planet
15 years ago
Posted by:
joedown
15 years ago
Not sure what I'm doing wrong here but I'm receiving an error when the custom action tries to run. Here is the part of the install log:
Here is what I have for my custom action:
CA_InstallOEMinf 50 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
Am I using the wrong name for my exe?
Action ended 9:20:47: InstallFinalize. Return value 1.
MSI (s) (50:E8) [09:20:47:625]: Doing action: CA_InstallOEMinf
Action 9:20:47: CA_InstallOEMinf.
Action start 9:20:47: CA_InstallOEMinf.
MSI (s) (50:E8) [09:20:47:625]: Note: 1: 2715 2: ICD_P_SERIES_DRIVER
MSI (s) (50:E8) [09:20:47:625]: Note: 1: 1721 2: CA_InstallOEMinf 3: 4:
Error 1721.There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: CA_InstallOEMinf, location: , command:
MSI (s) (50:E8) [09:20:48:609]: Product: Sony IC Recorder 3.0 -- Error 1721.There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: CA_InstallOEMinf, location: , command:
Action ended 9:20:48: CA_InstallOEMinf. Return value 3.
Action ended 9:20:48: INSTALL. Return value 3.
Here is what I have for my custom action:
CA_InstallOEMinf 50 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
Am I using the wrong name for my exe?
Posted by:
captain_planet
15 years ago
Posted by:
joedown
15 years ago
I think I'm getting closer now. I'm not sure what you mean by "foreign key into the file table." Here is the entry in the file table:
setupcopyoeminf.exe setupcopyoeminf.exe setupc~1.exe|setupcopyoeminf.exe 20992 16384 46
How did you come up with the number 18 for the type?
The error I'm getting now is more descriptive and shows the proper location now.
Sorry for so many questions but this is the first time I've ever needed to do a custom action.
setupcopyoeminf.exe setupcopyoeminf.exe setupc~1.exe|setupcopyoeminf.exe 20992 16384 46
How did you come up with the number 18 for the type?
The error I'm getting now is more descriptive and shows the proper location now.
Action ended 11:44:48: InstallFinalize. Return value 1.
MSI (s) (E8:24) [11:44:48:468]: Doing action: CA_InstallOEMinf
Action 11:44:48: CA_InstallOEMinf.
Action start 11:44:48: CA_InstallOEMinf.
MSI (s) (E8:24) [11:44:48:468]: Note: 1: 2715 2: ICD_P_SERIES_DRIVER
MSI (s) (E8:24) [11:44:48:515]: Note: 1: 1722 2: CA_InstallOEMinf 3: C:\Program Files\SONY\ICD-P Series Driver\setupcopyoeminf.exe 4:
Error 1722.There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action CA_InstallOEMinf, location: C:\Program Files\SONY\ICD-P Series Driver\setupcopyoeminf.exe, command:
MSI (s) (E8:24) [11:45:13:515]: Product: Sony IC Recorder 3.0 -- Error 1722.There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action CA_InstallOEMinf, location: C:\Program Files\SONY\ICD-P Series Driver\setupcopyoeminf.exe, command:
Action ended 11:45:13: CA_InstallOEMinf. Return value 3.
Action ended 11:45:13: INSTALL. Return value 3.
Sorry for so many questions but this is the first time I've ever needed to do a custom action.
Posted by:
captain_planet
15 years ago
There may be a file somewhere on your machine called msi.chm. This includes lots of handy information about Windows Installers. Do a search for 'Custom Action'. The number '18' denotes running an executable which is part of you windows installer, or to quote the help documentation 'EXE file that is installed with a product.'
As for the foreign key bit, do a google for it. For example, http://www.databasedev.co.uk/primary_foreign_key_constraints.html
As for the foreign key bit, do a google for it. For example, http://www.databasedev.co.uk/primary_foreign_key_constraints.html
Posted by:
joedown
15 years ago
I have gone over this custom action and I cannot figure out what is wrong. Everything seems to match what it should. Here are the lines for my custom action:
CustomAction
CA_InstallOEMinf 18 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
File
setupcopyoeminf.exe setupcopyoeminf.exe setupc~1.exe|setupcopyoeminf.exe 20992 16384 46
InstallExecuteSequence
CA_InstallOEMinf Not Installed 6650
I sequenced the custom action to run after the InstallFinalize action. The exe just needs to be launched and provided the path to its current location which is the ICD_P_SERIES_DRIVER directory. So I don't understand why this would be failing.
CustomAction
CA_InstallOEMinf 18 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
File
setupcopyoeminf.exe setupcopyoeminf.exe setupc~1.exe|setupcopyoeminf.exe 20992 16384 46
InstallExecuteSequence
CA_InstallOEMinf Not Installed 6650
I sequenced the custom action to run after the InstallFinalize action. The exe just needs to be launched and provided the path to its current location which is the ICD_P_SERIES_DRIVER directory. So I don't understand why this would be failing.
Posted by:
captain_planet
15 years ago
Posted by:
captain_planet
15 years ago
PS, Windows Installer documentation is also online...... http://msdn.microsoft.com/en-us/library/aa372048(VS.85).aspx
Posted by:
jmcfadyen
15 years ago
sorry to rain on your parade again captain_planet (no offence intended)
but when doing CA's that are modifying the system the golden rule is to do it in the deferred phase.
this was never inforced with earlier OS's but with the advent of Vista and UAC this is now a hard and fast (enforced rule). As such you need to schedule this as a deferred system context CA. So you may as well get it right on all OS's so the change is not so tough when you get to vista with UAC.
such as
msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate
Hexadecimal: 0x00000400 + 0x00000800
Decimal: 3072
Queues for execution at scheduled point within script. Executes with no user impersonation. Runs in system context.
you would also need to schedule prior to InstallFinalize action and where properties are required you would need to use the CustomAction data property to push values into the deferred script.
but when doing CA's that are modifying the system the golden rule is to do it in the deferred phase.
this was never inforced with earlier OS's but with the advent of Vista and UAC this is now a hard and fast (enforced rule). As such you need to schedule this as a deferred system context CA. So you may as well get it right on all OS's so the change is not so tough when you get to vista with UAC.
such as
msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate
Hexadecimal: 0x00000400 + 0x00000800
Decimal: 3072
Queues for execution at scheduled point within script. Executes with no user impersonation. Runs in system context.
you would also need to schedule prior to InstallFinalize action and where properties are required you would need to use the CustomAction data property to push values into the deferred script.
Posted by:
joedown
15 years ago
Posted by:
jmcfadyen
15 years ago
sorry i didnt provide enough detail there you need to add 3072 not change it to 3072.
By adding 3072 you are adding it to the script phase to execute in system context.
Just to add a little light on the topic heres some more detail.
During standards execution a number of processes are launched. Windows Installer is a service which runs as two com objects. These processes are client and server.
Under normal installation these two processes are launched almost immediately during installation. The UI phase is passed to the client (is classed as secure process). Other parts of the installation are handled in the server context.
When the deferred phase is reached two more processes are launched which are User / System. during the deferred phase actions are passed to the processes for execution. For this reason it is important that system changes are handled during deferred. If your writing registry / creating files / deleting files or modifying the system in any way it needs to be deferred as this is the ONLY time you have access to the user / system processes.
The downside of the deferred phase is that you are disconnected from the MSI and actually running a script gnerated from earlier phases. This means limited access to the database is possible. Because there is limited access to the database people often incorrectly place CA's in the immediate phase as its seems to be easier and under certain limited conditions it works.
hope this helps.
this blog has a little detail about it, but i need to revise it as there is a few bits of core information missing and the picture is crap and partially incorrect but you should get the idea.
http://johnmcfadyen.spaces.live.com/blog/cns!9DD01136FC094724!167.entry
By adding 3072 you are adding it to the script phase to execute in system context.
Just to add a little light on the topic heres some more detail.
During standards execution a number of processes are launched. Windows Installer is a service which runs as two com objects. These processes are client and server.
Under normal installation these two processes are launched almost immediately during installation. The UI phase is passed to the client (is classed as secure process). Other parts of the installation are handled in the server context.
When the deferred phase is reached two more processes are launched which are User / System. during the deferred phase actions are passed to the processes for execution. For this reason it is important that system changes are handled during deferred. If your writing registry / creating files / deleting files or modifying the system in any way it needs to be deferred as this is the ONLY time you have access to the user / system processes.
The downside of the deferred phase is that you are disconnected from the MSI and actually running a script gnerated from earlier phases. This means limited access to the database is possible. Because there is limited access to the database people often incorrectly place CA's in the immediate phase as its seems to be easier and under certain limited conditions it works.
hope this helps.
this blog has a little detail about it, but i need to revise it as there is a few bits of core information missing and the picture is crap and partially incorrect but you should get the idea.
http://johnmcfadyen.spaces.live.com/blog/cns!9DD01136FC094724!167.entry
Posted by:
joedown
15 years ago
ORIGINAL: jmcfadyen
sorry i didnt provide enough detail there you need to add 3072 not change it to 3072.
By adding 3072 you are adding it to the script phase to execute in system context.
I guess that's as simple as adding 3072+18 for 3090? If that is correct I am now getting an "Error 2762 Cannot write script record. Transaction not started." So I resequenced it to run just before InstallFinalize. This prevents the error and I see that the exe is getting run but it is not getting passed the right parameter. If I hard code the Target field to "C:\Program Files\Sony\ICD-P Series Driver" it works. But I would like to use an already defined variable. ICD_P_SERIES_DRIVER is the directory defined in the directory table. Is that not the correct way to do this? Using "$ICD_P_SERIES_DRIVER" for the Target field does not work. Any ideas?
Posted by:
jmcfadyen
15 years ago
hi joedown,
I suspected this would happen but I hadn't done this with a [#filepath]
At this point you are now entering the realm of CustomActionData. I know this seems considerably more difficult than it needs to be but this is acutally the correct method of doing this and supports installation under locked down user scenario's. (which ideally you want to do)
The issue as previously "partially" explained in my earlier post is that moving this action to the deferred sequence you lose access to the session. Because in the deferred phase you are actually running a script which was generated during the immediate phase. Due to the fact you are running the script you are disconected from the original MSI it is for this reason your properties are no longer available i.e. ( [#filekey] and [PropertyName] )
As such in order to make your CA work now you need to send the appropriate custom actions into the deferred phase. You do this by means of CustomActionData.
The CustomActionData methodology requires a throw and catch technique to be used. So during the immediate phase you throw information across into deferred phase. You then need to catch that information whilst in the deferered phase.
So in the immediate phase you need to create a property which contains all the values you want to throw across to the deferred phase. I do this by means of a Type 51 (set property CA)
Immediate Phase CA
SetDeferred, 51, DEFERREDVALUE, [#ICD_P_SERIES_DRIVER]
Then in the deferred phase you need to catch the property sent during the immediate phase.
You do this by naming your CA with the same name as the property set in the Immediate Phase. In this example you would need to set your current CA to this
Existing
CA_InstallOEMinf 50 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
New version
DEFERREDVALUE 50 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
alternatively if you want to catch CustomActionData value you can use the
session.property("CustomActionData") method within a VB script.
I hear this happen all too often I think I might blog about this tonight and setup some examples of how this should and shouldnt be done.
P.S. your other comment about moving the action before InstallFinalize is correct. You can ONLY sequence deferred CA's between InstallInitialize and InstallFinalize.
Hope this clears things up.
John
I suspected this would happen but I hadn't done this with a [#filepath]
At this point you are now entering the realm of CustomActionData. I know this seems considerably more difficult than it needs to be but this is acutally the correct method of doing this and supports installation under locked down user scenario's. (which ideally you want to do)
The issue as previously "partially" explained in my earlier post is that moving this action to the deferred sequence you lose access to the session. Because in the deferred phase you are actually running a script which was generated during the immediate phase. Due to the fact you are running the script you are disconected from the original MSI it is for this reason your properties are no longer available i.e. ( [#filekey] and [PropertyName] )
As such in order to make your CA work now you need to send the appropriate custom actions into the deferred phase. You do this by means of CustomActionData.
The CustomActionData methodology requires a throw and catch technique to be used. So during the immediate phase you throw information across into deferred phase. You then need to catch that information whilst in the deferered phase.
So in the immediate phase you need to create a property which contains all the values you want to throw across to the deferred phase. I do this by means of a Type 51 (set property CA)
Immediate Phase CA
SetDeferred, 51, DEFERREDVALUE, [#ICD_P_SERIES_DRIVER]
Then in the deferred phase you need to catch the property sent during the immediate phase.
You do this by naming your CA with the same name as the property set in the Immediate Phase. In this example you would need to set your current CA to this
Existing
CA_InstallOEMinf 50 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
New version
DEFERREDVALUE 50 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
alternatively if you want to catch CustomActionData value you can use the
session.property("CustomActionData") method within a VB script.
I hear this happen all too often I think I might blog about this tonight and setup some examples of how this should and shouldnt be done.
P.S. your other comment about moving the action before InstallFinalize is correct. You can ONLY sequence deferred CA's between InstallInitialize and InstallFinalize.
Hope this clears things up.
John
Posted by:
joedown
15 years ago
So if I understand correctly I will be adding one new custom action and will also need to add that custom action to the InstallExecuteSequence table and sequence it before my old CA_InstallOEMinf custom action? I'm also changing my old custom action name to DEFERREDVALUE as such I will need to change the entry in the Binary table as well? What you have described makes sense in reading but making it work it appears I have something wrong. Here are my table entries:
Binary
DEFERREDVALUE [Binary Data]
CustomAction
DEFERREDVALUE 3090 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
SetDeferred 51 DEFERREDVALUE [#ICD_P_SERIES_DRIVER]
InstallExecuteSequence
SetDeferred 6590
DEFERREDVALUE NOT Installed 6595
Binary
DEFERREDVALUE [Binary Data]
CustomAction
DEFERREDVALUE 3090 setupcopyoeminf.exe [#ICD_P_SERIES_DRIVER]
SetDeferred 51 DEFERREDVALUE [#ICD_P_SERIES_DRIVER]
InstallExecuteSequence
SetDeferred 6590
DEFERREDVALUE NOT Installed 6595
Posted by:
jmcfadyen
15 years ago
hi joedown,
there is no reason to change the binary table action.
the deferred CA
DEFERREDVALUE , 3090,setupcopyoeminf.exe , [#ICD_P_SERIES_DRIVER]
the bit in the read text is the part that references the binary table. so as such your binary table entry should remain as
setupcopyoeminf.exe , [binarydata]
a way that you can test the CustomActionData setup is actually working is this
Create a CA in Deferred as a vbs from embedded code.
in the vbs put this
msgbox session.property("CustomActionData")
this should result in the same value as this [#ICD_P_SERIES_DRIVER]
note this only works if the Custom action name in deferred matches the property generated in immediate. I know this is painful but its the only correct way to do it. I usually script this in the form of a macro to make it considerably easier.
If your using wise i could whip up a macro for you to perform this function quick and easy in the future.
there is no reason to change the binary table action.
the deferred CA
DEFERREDVALUE , 3090,
Create a CA in Deferred as a vbs from embedded code.
in the vbs put this
msgbox session.property("CustomActionData")
this should result in the same value as this [#ICD_P_SERIES_DRIVER]
note this only works if the Custom action name in deferred matches the property generated in immediate. I know this is painful but its the only correct way to do it. I usually script this in the form of a macro to make it considerably easier.
If your using wise i could whip up a macro for you to perform this function quick and easy in the future.
Posted by:
joedown
15 years ago
My only packaging suite I have available is Admin Studio but I have been trying to do this by only using Orca. It helps for me to understand it better. At this point I'm not sure what the problem is but I continue to receive Error 1722
MSI (s) (A8:1C) [08:19:33:968]: Executing op: ActionStart(Name=DEFERREDVALUE,,)
Action 8:19:33: DEFERREDVALUE.
MSI (s) (A8:1C) [08:19:33:968]: Executing op: CustomActionSchedule(Action=DEFERREDVALUE,ActionType=3090,Source=C:\Program Files\SONY\ICD-P Series Driver\setupcopyoeminf.exe,,)
MSI (s) (A8:1C) [08:19:34:015]: Note: 1: 1722 2: DEFERREDVALUE 3: C:\Program Files\SONY\ICD-P Series Driver\setupcopyoeminf.exe 4:
Error 1722.There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action DEFERREDVALUE, location: C:\Program Files\SONY\ICD-P Series Driver\setupcopyoeminf.exe, command:
MSI (s) (A8:1C) [08:20:00:328]: Product: Sony IC Recorder 3.0 -- Error 1722.There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action DEFERREDVALUE, location: C:\Program Files\SONY\ICD-P Series Driver\setupcopyoeminf.exe, command:
Posted by:
jmcfadyen
15 years ago
sorry i have been away for a bit.
try moving the SetDeferred action earlier (I usually put it just after InstallInitialize although it should work anywhere prior to DEFERREDVALUE)
Also from a troubleshooting perspective search for the SetDeferred CA to see if it is actually being set as required. The later CA will be no good if the previous one isn't correct.
Cheers,
John
try moving the SetDeferred action earlier (I usually put it just after InstallInitialize although it should work anywhere prior to DEFERREDVALUE)
Also from a troubleshooting perspective search for the SetDeferred CA to see if it is actually being set as required. The later CA will be no good if the previous one isn't correct.
Cheers,
John
Posted by:
joedown
15 years ago
I've discovered why it isn't working but I don't know how to fix it. The property in the Directory table ICD_P_SERIES_DRIVER resloves to C:\Program Files\SONY\ICD-P Series Driver\ The executable I need run cannot handle the backslash on the end of the path. It needs C:\Progam Files\Sony\ICD-P Series Driver
What would be the normal way of handling this? Is it possible to drop the last back slash before passing the property? Thanks for you help. I now have a better understanding of custom actions.
What would be the normal way of handling this? Is it possible to drop the last back slash before passing the property? Thanks for you help. I now have a better understanding of custom actions.
Posted by:
jmcfadyen
15 years ago
using an EXE CA I don't know of a way off the top of my head. Using a vbs CA its quite simple.
If the CA was VBS instead of EXE you could pull the property using this syntax.
it knows the correct value to get because of the name of the CA "DEFERREDVALUE"
then you could simply trim it like this
the only downside to this method is you can potentially lose context when shelling out to other calls.
after writing this you should just change the SetDeferred CA to push the correct value.
You could use another CA to trim the value using the above methods.
i.e.
SetProperty using Embedded VBS code. trim off the trailing slash.
then run the SetDeferred using the new value.
then run the DEFERREDVALUE.
in case your not aware of my blog there is some info in there about the sequences and i will soon follow up with one on CA's like this, with some examples. my blog is here
http://johnmcfadyen.spaces.live.com
cheers,
John
If the CA was VBS instead of EXE you could pull the property using this syntax.
myValue = session.property("CustomActionData")
it knows the correct value to get because of the name of the CA "DEFERREDVALUE"
then you could simply trim it like this
if right(myValue , 1) = "\" then
myValue = Left((myValue ), Len(myValue ) - 1)
end if
set objShell = CreateObject("Wscript.Shell")
objShell.Run "add command line here"
the only downside to this method is you can potentially lose context when shelling out to other calls.
after writing this you should just change the SetDeferred CA to push the correct value.
You could use another CA to trim the value using the above methods.
i.e.
SetProperty using Embedded VBS code. trim off the trailing slash.
then run the SetDeferred using the new value.
then run the DEFERREDVALUE.
in case your not aware of my blog there is some info in there about the sequences and i will soon follow up with one on CA's like this, with some examples. my blog is here
http://johnmcfadyen.spaces.live.com
cheers,
John
Posted by:
jmcfadyen
15 years ago
Posted by:
joedown
15 years ago
Thanks for the info and you help on this. I don't know VB enough to attempt to start doing custom action VB scripts. Ideally I wouldn't be running this exe in the first place but the example on this site for installing windows drivers is using it and a wise script. Since this program is getting installed on one machine I'm going to make an exception for it and just hardcode the path.
Posted by:
jmcfadyen
15 years ago
Posted by:
anonymous_9363
15 years ago
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.
so that the conversation will remain readable.