flcdrg / PowerShellWixExtension

Wix Extension for running PowerShell
Other
28 stars 12 forks source link

Platform bitness causes issues with WebAdministration module #4

Open mrchief opened 9 years ago

mrchief commented 9 years ago

Trying any cmdlet involving WebAdministration, causes throws errors during install. E.g., the following script:

import-module WebAdministration

new-webbinding -Name $WebsiteName -Protocol "https" -Port 443 -HostHeader $WebsiteName -SslFlags 1

will result in this error:

MSI (s) (58:A0) [17:10:43:104]: Hello, I'm your 32bit Elevated custom action server. SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSIF37C.tmp-\ SFXCA: Binding to CLR version v4.0.30319 Calling custom action PowerShellActions!PowerShellActions.CustomActions.PowerShellFilesElevatedDeferred PowerShellFilesElevatedDeferred start

PowerShell terminating error, returning Failure System.Management.Automation.CmdletInvocationException: Cannot retrieve the dynamic parameters for the cmdlet. Retrieving the COM class factory for component with CLSID {688EEEE5-6A7E-422F-B2E1-6AF00DC944A6} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)). ---> System.Management.Automation.ParameterBindingException: Cannot retrieve the dynamic parameters for the cmdlet. Retrieving the COM class factory for component with CLSID {688EEEE5-6A7E-422F-B2E1-6AF00DC944A6} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)). ---> System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {688EEEE5-6A7E-422F-B2E1-6AF00DC944A6} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)). at Microsoft.IIs.PowerShell.Framework.Configuration.QueryToStream(String xpath, String location, PipelineStreamWriter writer, QueryFlags queryFlags) at Microsoft.IIs.PowerShell.Framework.NamespaceNodeFactory.EnumerateInstances(TypeManager tm, CmdletProvider provider, String nodeTag, INamespaceNode parentNode) at Microsoft.IIs.PowerShell.Framework.NodeCollectionFactory.EnumerateInstances(TypeManager tm, CmdletProvider provider, String nodeTag, INamespaceNode parent) at Microsoft.IIs.PowerShell.Framework.NamespaceNode.ResetChildren(Boolean reRead) at Microsoft.IIs.PowerShell.Framework.NamespaceNode.get_Children() at Microsoft.IIs.PowerShell.Framework.NamespaceNode.GetMatchingChildNode(String& path, String& usedMatch) at Microsoft.IIs.PowerShell.Framework.NamespaceNode.SelectNamespaceNode(INamespaceNode parent, String path) at Microsoft.IIs.PowerShell.Framework.NamespaceNode.CreateFromAbsolutePath(INamespaceNode parent, String path) at Microsoft.IIs.PowerShell.Provider.ConfigurationProvider.GetParentPath(String path, String root) at Microsoft.IIs.PowerShell.Provider.ConfigurationProvider.GetChildName(String path) at System.Management.Automation.Provider.NavigationCmdletProvider.TokenizePathToStack(String path, String basePath) at System.Management.Automation.Provider.NavigationCmdletProvider.ContractRelativePath(String path, String basePath, Boolean allowNonExistingPaths, CmdletProviderContext context) at System.Management.Automation.LocationGlobber.GenerateRelativePath(PSDriveInfo drive, String path, Boolean escapeCurrentLocation, CmdletProvider providerInstance, CmdletProviderContext context) at System.Management.Automation.LocationGlobber.GetDriveRootRelativePathFromPSPath(String path, CmdletProviderContext context, Boolean escapeCurrentLocation, PSDriveInfo& workingDriveForPath, CmdletProvider& providerInstance) at System.Management.Automation.LocationGlobber.GetProviderPath(String path, CmdletProviderContext context, ProviderInfo& provider, PSDriveInfo& drive) at System.Management.Automation.LocationGlobber.GetGlobbedProviderPathsFromMonadPath(String path, Boolean allowNonexistingPaths, CmdletProviderContext context, ProviderInfo& provider, CmdletProvider& providerInstance) at System.Management.Automation.SessionStateInternal.NewPropertyDynamicParameters(String path, String propertyName, String type, Object value, CmdletProviderContext context) at Microsoft.PowerShell.Commands.NewItemPropertyCommand.GetDynamicParameters(CmdletProviderContext context) at Microsoft.PowerShell.Commands.CoreCommandBase.GetDynamicParameters() at System.Management.Automation.CmdletParameterBinderController.HandleCommandLineDynamicParameters(ParameterBindingException& outgoingBindingException) --- End of inner exception stack trace --- at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input) at Microsoft.IIs.PowerShell.Framework.Utility.InvokePipeShowError(PSCmdlet cmd, Pipeline pipe) at Microsoft.IIs.PowerShell.Provider.NewWebBindingCommand.ProcessRecord() at System.Management.Automation.Cmdlet.DoProcessRecord() at System.Management.Automation.CommandProcessor.ProcessRecord() --- End of inner exception stack trace --- at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input) at PowerShellActions.PowerShellTask.Execute() at PowerShellActions.CustomActions.FilesDeferred(Session session, String deferredProperty)

Googling (this and few others) indicate the root cause towards being a 32bit process trying to load a 64bit cmdlet (and its subsequent dependencies).

I'm not sure if changing the platform to x64 will be the best solution (even though x64 cmdlets will run on both 32/64 bit platforms). Alternatively, a separate 64 bit custom action will probably enable the user to choose between either and probably will be most flexible.

Thoughts?

flcdrg commented 9 years ago

Separate custom actions might be better. Not sure if we'd need to have a separate 64bit NuGet package to support this. Is your MSI compiled as 32bit or 64bit?

If we need to ensure we run 64 bit PowerShell, we might need to do something like this - http://stackoverflow.com/questions/19055924/how-to-launch-64-bit-powershell-from-32-bit-cmd-exe.

Is this something you'd be interested in implementing?

mrchief commented 9 years ago

My MSI is compiled as 64 bit and despite all theories about how SFXCA.dll should automatically load the appropriate bit server, evidence points to contrary.

I can give it a try but I think Wix documentation is not tested - more of theory and "should happen" stuff rather than actually battle tested. So a 64bit CA also may not solve the underlying issue (their own 64bit CA still loads the 32 bit server).

Currently I'm invoking PowerShell via a custom action and executing my stuff in ps1 script.

flcdrg commented 8 years ago

Probably also need to do this http://stackoverflow.com/questions/7769580/how-should-i-create-or-upload-a-32-bit-and-64-bit-nuget-package to support referencing 64bit custom action

mrchief commented 8 years ago

@flcdrg I don't have a 32 bit package (and luckily I don't have to support both x86 and x64). Its totally x64 right now.

Eternal21 commented 7 years ago

Same issue. Tried to use this way of scripting to get around WiX not being able to set WebAppPool to 'No Managed Code' (https://github.com/wixtoolset/issues/issues/5226). Sadly it requires WebAdministration and powershell chokes on it with the same error.