问题
My installer has a custom action which contacts a windows service and set some parameters. In order to successfully use the service, it must be run with the elevated privileges.
In the first time install when a user clicks on the Install button, it is presented with the UAC prompt and install completes successfully. However, when a user decides to change the product(add new feature), call to the service will fail! This happens because installer is not run in the privileged mode. When I start the installer from a command prompt with administrative rights, change operation also completes successfully.
I've came across the following article which suggests creating a bootstrapper. Is there any easier way to accomplish this?
Did I implement the custom action correctly?. Here's the custom action code
<CustomAction Id='SetParams' BinaryKey='Setup.CustomAction' DllEntry='SetParameters' Execute='deferred' Impersonate='no' Return='asyncWait'/>
<Binary Id='Setup.CustomAction' SourceFile='$(var.CustomActionDll)' />
<InstallExecuteSequence>
<Custom Action='SetParams' Before='InstallFinalize'><![CDATA[REMOVE <> "ALL"]]></Custom>
</InstallExecuteSequence>
Update: After Cosmin's comment, I realized I was accessing the session data in CA. SetParams CA uses dynamic properties generated in the UI sequence. To access data in deferred CA, I've created an immediate CA which dynamically extracts this data and puts it in the CustomActionData.
<CustomAction Id='SaveParams' BinaryKey='Setup.CustomAction' DllEntry='SaveParameters' Execute='immediate' Return='check'/>
<CustomAction Id='SetParams' BinaryKey='Setup.CustomAction' DllEntry='SetParameters' Execute='deferred' Impersonate='no' Return='check' />
<Custom Action='SaveParams' Before='SetParams'><![CDATA[REMOVE <> "ALL"]]></Custom>
<Custom Action='SetParams' Before='InstallFinalize'><![CDATA[REMOVE <> "ALL"]]></Custom>
Following is the part of SaveParameters method in the custom action
propertyName = moduleInfo.GetPropertyName(moduleParameter.Name);
customActionData.Append(string.Format(CultureInfo.InvariantCulture, "{0}={1};", propertyName, session[propertyName]));
This approach works! When started from admin cmd session[propertyName] returns the correct value, but when I run the installer change from non-elevated cmd prompt, I cannot access the property values in the immediate CA - session[propertyName] returns empty string ?!
I can access the (static) property defined in wxs file
<Property Id="INSTALL" Secure="yes" />
but not the one's I've added in some other immediate custom action in the UI sequence like this
session[property] = parameters[paramcount++];
回答1:
Deferred custom action with no impersonation attribute set will ensure that the CA is run in elevated mode.
I've added a new question to address the other issue which emerged.
Solution to accessing dynamic property value issue
- Immediate action which reads properties to be moved from execution sequence to UI sequence
- Actions in execution phase can access data from secure properties as stated in the question. If the properties are dynamically created in CA, they must be added to SecureCustomProperties system property. Separator char is ';'."
来源:https://stackoverflow.com/questions/9096452/wix-installer-how-to-run-change-with-administrative-privileges-when-run-from-u