Investigation for Issue #3925

Topics: General
Jan 2, 2014 at 3:57 AM
Hi,

I am looking into Issue #3925. It looks like NuGet needs to refresh its project cache after running package scripts but I am not quite sure how to do that. I tried to force a refresh of SolutionManager._projectCache without much success. Would someone have suggestions about where to make the fix?

Here is what I have so far: the call to project.ProjectItems in ProjectExtensions.GetProjectItems() throws COMException E_FAIL (0x80004005) "Project unavailable." when trying to uninstall the package. The callstack is:
NuGet.VisualStudio.dll!NuGet.VisualStudio.ProjectExtensions.GetProjectItems(EnvDTE.Project project, string folderPath, bool createIfNotExists) Line 78  C#
NuGet.VisualStudio.dll!NuGet.VisualStudio.ProjectExtensions.GetProjectItem(EnvDTE.Project project, string path) Line 111    C#
NuGet.VisualStudio.dll!NuGet.VisualStudio.ProjectExtensions.DeleteProjectItem(EnvDTE.Project project, string path) Line 163 C#
NuGet.VisualStudio.dll!NuGet.VisualStudio.VsProjectSystem.DeleteFile(string path) Line 142  C#
NuGet.Core.dll!NuGet.FileSystemExtensions.DeleteFileSafe.AnonymousMethod__e() Line 121  C#
NuGet.Core.dll!NuGet.FileSystemExtensions.Attempt(System.Action action, int retries, int delayBeforeRetry) Line 241 C#
NuGet.Core.dll!NuGet.FileSystemExtensions.DoSafeAction(System.Action action, NuGet.ILogger logger) Line 227 C#
NuGet.Core.dll!NuGet.FileSystemExtensions.DeleteFileSafe(NuGet.IFileSystem fileSystem, string path) Line 121    C#
NuGet.Core.dll!NuGet.FileSystemExtensions.DeleteFileSafe(NuGet.IFileSystem fileSystem, string path, System.Func<System.IO.Stream> streamFactory) Line 140   C#
NuGet.Core.dll!NuGet.ProjectSystemExtensions.DeleteFiles(NuGet.IProjectSystem project, System.Collections.Generic.IEnumerable<NuGet.IPackageFile> files, System.Collections.Generic.IEnumerable<NuGet.IPackage> otherPackages, System.Collections.Generic.IDictionary<NuGet.FileTransformExtensions,NuGet.IPackageFileTransformer> fileTransformers) Line 187   C#
NuGet.Core.dll!NuGet.ProjectManager.RemovePackageReferenceFromProject(NuGet.IPackage package) Line 463  C#
NuGet.Core.dll!NuGet.ProjectManager.Execute(NuGet.PackageOperation operation) Line 215  C#
NuGet.Core.dll!NuGet.ProjectManager.Execute(NuGet.IPackage package, NuGet.IPackageOperationResolver resolver) Line 173  C#
NuGet.Core.dll!NuGet.ProjectManager.RemovePackageReference(NuGet.IPackage package, bool forceRemove, bool removeDependencies) Line 413  C#
NuGet.Core.dll!NuGet.ProjectManager.RemovePackageReference(string packageId, bool forceRemove, bool removeDependencies) Line 407    C#
NuGet.VisualStudio.dll!NuGet.VisualStudio.VsPackageManager.RemovePackageReference.AnonymousMethod__4d() Line 1136   C#
NuGet.VisualStudio.dll!NuGet.VisualStudio.VsPackageManager.RunProjectAction(NuGet.IProjectManager projectManager, System.Action action) Line 1460   C#
NuGet.VisualStudio.dll!NuGet.VisualStudio.VsPackageManager.RemovePackageReference(NuGet.IProjectManager projectManager, string packageId, bool forceRemove, bool removeDependencies) Line 1136  C#
NuGet.VisualStudio.dll!NuGet.VisualStudio.VsPackageManager.UninstallPackage(NuGet.IProjectManager projectManager, string packageId, NuGet.SemanticVersion version, bool forceRemove, bool removeDependencies, NuGet.ILogger logger) Line 239    C#
NuGet.Cmdlets.dll!NuGet.PowerShell.Commands.UninstallPackageCommand.ProcessRecordCore() Line 59 C#
NuGet.Cmdlets.dll!NuGet.PowerShell.Commands.NuGetBaseCommand.ProcessRecord() Line 122   C#
System.Management.Automation.dll!System.Management.Automation.Cmdlet.DoProcessRecord()  Unknown
I was able to simplify the scripts a bit to hit that issue
  • A.nuspec:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>A</id>
    <version>1.0.6</version>
    <authors>X</authors>
    <description>Y</description>
  </metadata>
  <files>
    <file src="Install.ps1" target="tools\" /> 
    <file src="Uninstall.ps1" target="tools\" /> 
    <file src="placeholder.txt" target="content\" /> 
  </files>
</package>
placeholder.txt is a random file.
  • Install.ps1:
param($installPath, $toolsPath, $package, $project)

$projectName = $dte.Solution.Properties.Item("Name").Value + "\" + $project.Name
$projectUniqueName = $project.UniqueName

function Select-SolutionWindow()
{
    $window = $dte.Windows.Item([EnvDTE.Constants]::vsWindowKindSolutionExplorer)
    $window.Activate()
    $window.Object.GetItem($projectName).Select([EnvDTE.vsUISelectionType]::vsUISelectionTypeSelect)
}

Write-Host ("Adding package to project " + $projectUniqueName);
$project.Save();

Write-Host ("Unloading project " + $projectUniqueName)
Select-SolutionWindow
$dte.ExecuteCommand("Project.UnloadProject", "")
    
Write-Host ("Reloading project " + $projectUniqueName)
Select-SolutionWindow
$dte.ExecuteCommand("Project.ReloadProject", "")
  • Uninstall.ps1 :
param($installPath, $toolsPath, $package, $project)

$projectName = $dte.Solution.Properties.Item("Name").Value + "\" + $project.Name
$projectUniqueName = $project.UniqueName

function Select-SolutionWindow()
{
    $window = $dte.Windows.Item([EnvDTE.Constants]::vsWindowKindSolutionExplorer)
    $window.Activate()
    $window.Object.GetItem($projectName).Select([EnvDTE.vsUISelectionType]::vsUISelectionTypeSelect)
}

Write-Host ("Removing package from project " + $projectUniqueName);
$project.Save();

Write-Host ("Unloading project " + $projectUniqueName)
Select-SolutionWindow
$dte.ExecuteCommand("Project.UnloadProject", "")
    
Write-Host ("Reloading project " + $projectUniqueName)
Select-SolutionWindow
$dte.ExecuteCommand("Project.ReloadProject", "")
In the Package Manager Console, run:
Install-Package A
Uninstall-Package A