public virtual void AddImport(string targetFullPath, ImportLocation location) { Assumes.NotNullOrEmpty(targetFullPath); NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(ProjectFullPath), targetFullPath); AddImportStatement(relativeTargetPath, location); await SaveProjectAsync(); // notify the project system of the change UpdateImportStamp(VsProjectAdapter); }); }
public virtual async Task AddReferenceAsync(string referencePath) { if (referencePath == null) { throw new ArgumentNullException(nameof(referencePath)); } var name = Path.GetFileNameWithoutExtension(referencePath); var projectName = string.Empty; var projectFullPath = string.Empty; var assemblyFullPath = string.Empty; var dteProjectFullName = string.Empty; var dteOriginalPath = string.Empty; var resolvedToPackage = false; try { // Perform all DTE operations on the UI thread await NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async delegate { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // Read DTE properties from the UI thread projectFullPath = ProjectFullPath; projectName = ProjectName; dteProjectFullName = VsProjectAdapter.FullName; // Get the full path to the reference assemblyFullPath = Path.Combine(projectFullPath, referencePath); // Add a reference to the project dynamic reference; try { // First try the References3.AddFiles API, as that will incur fewer // design-time builds. References3.AddFiles(new[] { assemblyFullPath }, out var referencesArray); var references = (VSLangProj.Reference[])referencesArray; reference = references[0]; } catch (Exception e) { if (e is InvalidCastException) { // We've encountered a project system that doesn't implement References3, or // there's some sort of setup issue such that we can't find the library with // the References3 type. Send a report about this. TelemetryActivity.EmitTelemetryEvent(new TelemetryEvent("References3InvalidCastException")); } // If that didn't work, fall back to References.Add. reference = References.Add(assemblyFullPath); } if (reference != null) { dteOriginalPath = GetReferencePath(reference); // If path != fullPath, we need to set CopyLocal thru msbuild by setting Private // to true. // This happens if the assembly appears in any of the search paths that VS uses to // locate assembly references. // Most commonly, it happens if this assembly is in the GAC or in the output path. // The path may be null or for some project system it can be "". resolvedToPackage = !string.IsNullOrWhiteSpace(dteOriginalPath) && IsSamePath(dteOriginalPath, assemblyFullPath); if (resolvedToPackage) { // Set reference properties (if needed) TrySetCopyLocal(reference); TrySetSpecificVersion(reference); } } }); if (!resolvedToPackage) { // This should be done off the UI thread // Get the msbuild project for this project var buildProject = EnvDTEProjectUtility.AsMSBuildEvaluationProject(dteProjectFullName); if (buildProject != null) { // Get the assembly name of the reference we are trying to add var assemblyName = AssemblyName.GetAssemblyName(assemblyFullPath); // Try to find the item for the assembly name var item = (from assemblyReferenceNode in buildProject.GetAssemblyReferences() where AssemblyNamesMatch(assemblyName, assemblyReferenceNode.Item2) select assemblyReferenceNode.Item1).FirstOrDefault(); if (item != null) { // Add the <HintPath> metadata item as a relative path var projectPath = PathUtility.EnsureTrailingSlash(projectFullPath); var relativePath = PathUtility.GetRelativePath(projectPath, referencePath); item.SetMetadataValue("HintPath", relativePath); // Set <Private> to true item.SetMetadataValue("Private", "True"); FileSystemUtility.MakeWritable(dteProjectFullName); // Change to the UI thread to save NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // Save the project after we've modified it. await SaveProjectAsync(); }); } } else { // The reference cannot be changed by modifying the project file. // This could be a failure, however that could be a breaking // change if there is a non-msbuild project system relying on this // to skip references. // Log a warning to let the user know that their reference may have failed. NuGetProjectContext.Log( ProjectManagement.MessageLevel.Warning, Strings.FailedToAddReference, name); } } }