PowerShell / PowerShell/PSResourceGet

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

Abierto
#78 3 comentarios 3 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
C#
Estrellas
576
Forks
114
Merge medio
1 d 2 h
PR fusionados (30 d)
7

Descripción

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...}                                        

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con la reproducción de Update-Module usando PANSIES y las versiones indicadas de PowerShellGet y PackageManagement. Traza la ruta de Install-Package alrededor del binario bloqueado y del reemplazo fallido. Se considera terminado cuando una actualización de prerelease informa con precisión del problema de bloqueo, conserva el módulo existente cuando la instalación falla y se ejecuta correctamente después de que el módulo deje de estar en uso.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
powershell
Área
cli, tooling
Tipo de issue
Error
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
28/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.