/// <summary> /// Find all files that are to be considered SDK Resolvers. Pattern will match /// Root\SdkResolver\(ResolverName)\(ResolverName).dll. /// </summary> /// <param name="rootFolder"></param> /// <param name="location"></param> /// <returns></returns> internal virtual IList <string> FindPotentialSdkResolvers(string rootFolder, ElementLocation location) { var assembliesList = new List <string>(); if ((string.IsNullOrEmpty(rootFolder) || !FileUtilities.DirectoryExistsNoThrow(rootFolder)) && AdditionalResolversFolder == null) { return(assembliesList); } DirectoryInfo[] subfolders = GetSubfolders(rootFolder, AdditionalResolversFolder); foreach (var subfolder in subfolders) { var assembly = Path.Combine(subfolder.FullName, $"{subfolder.Name}.dll"); var manifest = Path.Combine(subfolder.FullName, $"{subfolder.Name}.xml"); var assemblyAdded = TryAddAssembly(assembly, assembliesList); if (!assemblyAdded) { assemblyAdded = TryAddAssemblyFromManifest(manifest, subfolder.FullName, assembliesList, location); } if (!assemblyAdded) { ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(location), "SdkResolverNoDllOrManifest", subfolder.FullName); } } return(assembliesList); }
protected virtual void LoadResolvers(string resolverPath, LoggingContext loggingContext, ElementLocation location, List <SdkResolver> resolvers) { Assembly assembly; try { assembly = LoadResolverAssembly(resolverPath, loggingContext, location); } catch (Exception e) { ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(location), e, "CouldNotLoadSdkResolverAssembly", resolverPath, e.Message); return; } foreach (Type type in GetResolverTypes(assembly)) { try { resolvers.Add((SdkResolver)Activator.CreateInstance(type)); } catch (TargetInvocationException e) { // .NET wraps the original exception inside of a TargetInvocationException which masks the original message // Attempt to get the inner exception in this case, but fall back to the top exception message string message = e.InnerException?.Message ?? e.Message; ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(location), e.InnerException ?? e, "CouldNotLoadSdkResolver", type.Name, message); } catch (Exception e) { ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(location), e, "CouldNotLoadSdkResolver", type.Name, e.Message); } } }
/// <summary> /// Determines what the real tools version is. /// </summary> private string ResolveToolsVersion(BuildRequestData data, string defaultToolsVersion, Internal.Utilities.GetToolset getToolset) { if (data.ExplicitToolsVersionSpecified) { return(data.ExplicitlySpecifiedToolsVersion); } // None was specified by the call, fall back to the project's ToolsVersion attribute if (data.ProjectInstance != null) { return(data.ProjectInstance.Toolset.ToolsVersion); } else if (FileUtilities.IsVCProjFilename(data.ProjectFullPath)) { ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(data.ProjectFullPath), "ProjectUpgradeNeededToVcxProj", data.ProjectFullPath); } else if (!FileUtilities.IsSolutionFilename(data.ProjectFullPath)) { // If the file does not exist, it's a failure of the host, possibly msbuild.exe; so it's an ArgumentException here ErrorUtilities.VerifyThrowArgument(File.Exists(data.ProjectFullPath), "ProjectFileNotFound", data.ProjectFullPath); string toolsVersionFromFile = null; // We use an XmlTextReader to sniff, rather than simply loading a ProjectRootElement into the cache, because // quite likely this won't be the node on which the request will be built, so we'd be loading the ProjectRootElement // on this node unnecessarily. toolsVersionFromFile = XmlUtilities.SniffAttributeValueFromXmlFile(ProjectFullPath, XMakeAttributes.project, XMakeAttributes.toolsVersion); // Instead of just using the ToolsVersion from the file, though, ask our "source of truth" what the ToolsVersion // we should use is. This takes into account the various environment variables that can affect ToolsVersion, etc., // to make it more likely that the ToolsVersion we come up with is going to be the one actually being used by the // project at build time. string toolsVersionToUse = Utilities.GenerateToolsVersionToUse ( data.ExplicitlySpecifiedToolsVersion, toolsVersionFromFile, getToolset, defaultToolsVersion ); return(toolsVersionToUse); } // Couldn't find out the right ToolsVersion any other way, so just return the default. return(defaultToolsVersion); }
private bool TryAddAssemblyFromManifest(string pathToManifest, string manifestFolder, List <string> assembliesList, ElementLocation location) { if (!string.IsNullOrEmpty(pathToManifest) && !FileUtilities.FileExistsNoThrow(pathToManifest)) { return(false); } string path = null; try { // <SdkResolver> // <Path>...</Path> // </SdkResolver> var manifest = SdkResolverManifest.Load(pathToManifest); if (manifest == null || string.IsNullOrEmpty(manifest.Path)) { ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(location), "SdkResolverDllInManifestMissing", pathToManifest, string.Empty); } path = FileUtilities.FixFilePath(manifest.Path); } catch (XmlException e) { // Note: Not logging e.ToString() as most of the information is not useful, the Message will contain what is wrong with the XML file. ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(location), e, "SdkResolverManifestInvalid", pathToManifest, e.Message); } if (!Path.IsPathRooted(path)) { path = Path.Combine(manifestFolder, path); path = Path.GetFullPath(path); } if (!TryAddAssembly(path, assembliesList)) { ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(location), "SdkResolverDllInManifestMissing", pathToManifest, path); } return(true); }
/// <summary> /// Determines what the real tools version is. /// </summary> private string ResolveToolsVersion(BuildRequestData data, string defaultToolsVersion) { if (data.ExplicitToolsVersionSpecified) { return(data.ExplicitlySpecifiedToolsVersion); } // None was specified by the call, fall back to the project's ToolsVersion attribute if (data.ProjectInstance != null) { return(data.ProjectInstance.Toolset.ToolsVersion); } if (FileUtilities.IsVCProjFilename(data.ProjectFullPath)) { ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(data.ProjectFullPath), "ProjectUpgradeNeededToVcxProj", data.ProjectFullPath); } // We used to "sniff" the tools version from the project XML by opening it and reading the attribute. // This was causing unnecessary overhead since the ToolsVersion is never really used. Instead we just // return the default tools version return(defaultToolsVersion); }