Skip to content

Installing fails catastrophically when PreRelease modules have a binary assembly in use #78

Open
@Jaykul

Description

@Jaykul

PreRelease modules that have binary assemblies cannot be upgraded if they are imported in any PowerShell session on the machine, because the binary will be locked.

It's practically impossible to update a PreRelease version of a module with binaries if you import it in your profile.

Expected Behavior

Update-Module should work, and should never break a working module.

Current Behavior:

PackageManagement\Install-Package : Administrator rights are required to install or update. Log on to the computer with an account that has Administrator
rights, and then try again, or install by adding "-Scope CurrentUser" to your command. You can also try running the Windows PowerShell session with elevated
rights (Run as Administrator).
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.6.7\PSModule.psm1:12955 char:20
+ ...           $sid = PackageManagement\Install-Package @PSBoundParameters
+                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (System.Collections.ArrayList:String) [Install-Package], Exception
    + FullyQualifiedErrorId : AdministratorRightsNeededOrSpecifyCurrentUserScope,Copy-Module,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage

Unfortunately, this error message is utterly incorrect, in every way

First: administrator rights won't help. What we need to do is to close every instance of PowerShell (including in terminals, in editors, etc), and then open a new instance with -noprofile (NOTE: if we're trying to upgrade PSReadLine -- try using ISE, because that's the only way to avoid using PSReadLine).

Second: "adding -Scope CurrentUser to your command" won't help. That's not a valid parameter for this command! 🙈💥💀🔥 And in any case, we're actually trying to upgrade to CurrentUser scope! The reason we can't is because the file is locked, not because we are trying to install somewhere we're not allowed to.

Third: Why are we repeating the advice to run "the Windows PowerShell session with elevated
rights (Run as Administrator)." For goodness sakes!

Additionally, the failed upgrade results in obliterating the existing install of the module.

Because the previous install was in the same folder, it's now gone (except for that binary file) -- AND WE CANNOT REINSTALL IT for the same reason the upgrade failed.

Possible Solution

Two possible solutions. My favorite would be:

  1. Always install modules into folders with full semver names
  2. If there's a +metadata or -postfix create a junction point with the System.Version name. I.e. 4.0.0 -> 4.0.0-beta02 ...
  3. When updating a pre-release, just adjust the junction after the install is successful.

Alternatively, if junctions are not supported in the file system:

  1. When PowerShellGet realizes that it's going to be installing to the same folder as an existing module, it should move all of the files to a SemVer-named folder before attempting to install the new version.
  2. If the install fails for any reason (e.g. network interruption), it should clean up by moving the old version back!
  3. The old pre-release version could even be left behind (and restored if the user removes the new pre-release), and could be cleaned up explicitly by the user at a later date -- just like regular versions.

Steps To Reproduce:

  1. Install-Module PANSIES -RequiredVersion 1.4.0-beta02 -Scope CurrentUser
  2. Import-Module PANSIES
  3. Get-InstalledModule Pansies and see you have beta02
  4. Attempt to Update-Module PANSIES -AllowPrerelease (should update to -beta03 but will instead die in a mysterious fire)
  5. Get-InstalledModule Pansies and see you don't have beta03, nor do you have beta02 anymore!

Context

My module PANSIES, and the built-in PSReadLine are just two examples of this which I have imported in my profile (or which PowerShell imports by default) which simply break when you try to update them.

Your Environment

> $PSVersionTable

Name                           Value                                                                                                                          
----                           -----                                                                                                                          
PSVersion                      5.1.17134.228                                                                                                                  
PSEdition                      Desktop                                                                                                                        
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                        
BuildVersion                   10.0.17134.228                                                                                                                 
CLRVersion                     4.0.30319.42000                                                                                                                
WSManStackVersion              3.0                                                                                                                            
PSRemotingProtocolVersion      2.3                                                                                                                            
SerializationVersion           1.1.0.1                                                                                                                        

> Get-Module PowerShellGet

ModuleType Version    Name                                ExportedCommands                                                                                    
---------- -------    ----                                ----------------                                                                                    
Script     1.6.7      PowerShellGet                       {Find-Command, Find-DscResource, Find-Module, Find-RoleCapability...}                               


> Get-Module -ListAvailable PowerShellGet,PackageManagement

ModuleType Version    Name                                ExportedCommands                                                                                    
---------- -------    ----                                ----------------                                                                                    
Script     1.1.7.2    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}                              
Script     1.1.7.0    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}                              
Script     1.1.1.0    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}                              
Binary     1.0.0.1    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}                              
Script     1.6.7      PowerShellGet                       {Find-Command, Find-DSCResource, Find-Module, Find-RoleCapability...}                               
Script     1.6.0      PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}                                        
Script     1.1.3.1    PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}                                        
Script     1.0.0.1    PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}                                        

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions