private Assembly ResolveAssembly(ProjectId projectId, string assemblyName) { this.AssertIsForeground(); if (_workspace == null) { return(null); } IVsHierarchy hierarchy; string targetMoniker; if (!_workspace.TryGetHierarchy(projectId, out hierarchy) || !hierarchy.TryGetProperty((__VSHPROPID)__VSHPROPID4.VSHPROPID_TargetFrameworkMoniker, out targetMoniker) || targetMoniker == null) { return(null); } try { // Below we use the DesignTimeAssemblyResolver functionality of VS to // determine if we can resolve the specified assembly name in the context // of this project. However, this service does not do the right thing // in UWP apps. Specifically, it *will* resolve the assembly to a // reference assembly, even though that's never what we want. In order // to deal with that, we put in this little check where we do not allow // reference assembly resolution if the projects TargetFrameworkMoniker // is ".NETCore, Version=5.0" or greater. var frameworkName = new FrameworkName(targetMoniker); if (StringComparer.OrdinalIgnoreCase.Equals(frameworkName.Identifier, ".NETCore") && frameworkName.Version >= new Version(major: 5, minor: 0)) { return(null); } } catch (ArgumentException) { // Something wrong with our TFM. We don't have enough information to // properly resolve this assembly name. return(null); } try { var frameworkProvider = new VsTargetFrameworkProvider( _workspace.GetVsService <SVsFrameworkMultiTargeting, IVsFrameworkMultiTargeting>(), targetMoniker, _workspace.GetVsService <SVsSmartOpenScope, IVsSmartOpenScope>()); return(frameworkProvider.GetReflectionAssembly(new AssemblyName(assemblyName))); } catch (InvalidOperationException) { // VsTargetFrameworkProvider throws InvalidOperationException in the // some cases (like when targetting packs are missing). In that case // we can't resolve this path. return(null); } }
/// <summary> /// Updates app. or web.config to include connection strings, registers the build provider /// for WebSite projects and the assembly for WebApp projects /// </summary> internal static void UpdateConfig(ModelBuilderSettings settings) { var metadataFileNames = ConnectionManager.GetMetadataFileNamesFromArtifactFileName(settings.Project, settings.ModelPath, PackageManager.Package); if (settings.GenerationOption == ModelGenerationOption.GenerateFromDatabase || settings.GenerationOption == ModelGenerationOption.GenerateDatabaseScript) { if (settings.SaveConnectionStringInAppConfig && !settings.SaveToWebConfig) { // save connection string in App Config UpdateAppConfig(metadataFileNames, settings); } else if (settings.SaveConnectionStringInAppConfig && settings.SaveToWebConfig) { // save connection string in Web Config UpdateWebConfig(metadataFileNames, settings); } } var containingProject = settings.Project; // regardless of GenerationOption we always need to register the build // provider for web site projects and the assembly for web app projects if (settings.VSApplicationType == VisualStudioProjectSystem.Website) { RegisterBuildProvidersInWebConfig(containingProject); } // Ensure that System.Data.Entity.Design reference assemblies are added in the web.config. if (settings.VSApplicationType == VisualStudioProjectSystem.WebApplication || settings.VSApplicationType == VisualStudioProjectSystem.Website) { // Get the correct assembly name based on target framework var projectHierarchy = VsUtils.GetVsHierarchy(containingProject, Services.ServiceProvider); Debug.Assert(projectHierarchy != null, "Could not get the IVsHierarchy from the EnvDTE.Project"); if (projectHierarchy != null) { var targetInfo = PackageManager.Package.GetService(typeof(SVsFrameworkMultiTargeting)) as IVsFrameworkMultiTargeting; var openScope = PackageManager.Package.GetService(typeof(SVsSmartOpenScope)) as IVsSmartOpenScope; Debug.Assert(targetInfo != null, "Unable to get IVsFrameworkMultiTargeting from service provider"); var targetFrameworkMoniker = VsUtils.GetTargetFrameworkMonikerForProject(containingProject, PackageManager.Package); if ((targetInfo != null) && (openScope != null) && settings.VSApplicationType == VisualStudioProjectSystem.Website) { var provider = new VsTargetFrameworkProvider(targetInfo, targetFrameworkMoniker, openScope); var dataEntityDesignAssembly = provider.GetReflectionAssembly(new AssemblyName("System.Data.Entity.Design")); if (dataEntityDesignAssembly != null) { RegisterAssemblyInWebConfig(containingProject, dataEntityDesignAssembly.FullName); } } } } }
private static Assembly TryLoad(VsTargetFrameworkProvider provider, Reference reference) { try { var name = AssemblyName.GetAssemblyName(reference.Path); return(provider.GetReflectionAssembly(name)); } catch (Exception e) { tracer.Warn(e, Strings.IProjectNodeExtensions.FailedToLoadAssembly(reference.Name, reference.Path)); return(null); } }
private IEnumerable <Type> GetAvailableTypes(Type assignableTo) { var allTypes = new List <Type>(); // Get nearest project scope var project = this.solution.GetCurrentProjectScope(); var hierarchy = project.As <IVsHierarchy>(); var vsProject = hierarchy as IVsProject; Microsoft.VisualStudio.OLE.Interop.IServiceProvider olesp; // The design-time assembly resolution (DTAR) must be retrieved from a // local service provider for the project. This is the magic goo. if (vsProject.GetItemContext(Microsoft.VisualStudio.VSConstants.VSITEMID_ROOT, out olesp) == Microsoft.VisualStudio.VSConstants.S_OK) { var localservices = new ServiceProvider(olesp); var openScope = this.serviceProvider.GetService(typeof(SVsSmartOpenScope)) as IVsSmartOpenScope; var dtar = (IVsDesignTimeAssemblyResolution)localservices.GetService(typeof(SVsDesignTimeAssemblyResolution)); // As suggested by Christy Henriksson, we reuse the type discovery service // but just for the IDesignTimeAssemblyLoader interface. The actual // assembly reading is done by the TFP using metadata only :) var dts = (DynamicTypeService)this.serviceProvider.GetService(typeof(DynamicTypeService)); var ds = dts.GetTypeDiscoveryService(hierarchy); var dtal = ds as IDesignTimeAssemblyLoader; var provider = new VsTargetFrameworkProvider(dtar, dtal, openScope); var references = project.GetAssemblyReferences(); foreach (var reference in references) { try { var name = AssemblyName.GetAssemblyName(reference.Path); allTypes.AddRange(provider .GetReflectionAssembly(name) .GetExportedTypes() .Where(t => t.IsAssignableTo(assignableTo))); } catch (Exception) { continue; } } } return(allTypes); }
public string ResolveAssemblyPath(ProjectId projectId, string assemblyName) { this.AssertIsForeground(); if (_workspace != null) { IVsHierarchy hierarchy; string targetMoniker; if (_workspace.TryGetHierarchy(projectId, out hierarchy) && hierarchy.TryGetProperty((__VSHPROPID)__VSHPROPID4.VSHPROPID_TargetFrameworkMoniker, out targetMoniker) && targetMoniker != null) { try { var frameworkProvider = new VsTargetFrameworkProvider( _workspace.GetVsService<SVsFrameworkMultiTargeting, IVsFrameworkMultiTargeting>(), targetMoniker, _workspace.GetVsService<SVsSmartOpenScope, IVsSmartOpenScope>()); var assembly = frameworkProvider.GetReflectionAssembly(new AssemblyName(assemblyName)); // Codebase specifies where the assembly is on disk. However, it's in // full URI format (i.e. file://c:/...). This will allow us to get the // actual local in the normal path format. Uri uri; if (Uri.TryCreate(assembly.CodeBase, UriKind.RelativeOrAbsolute, out uri)) { return uri.LocalPath; } } catch (InvalidOperationException) { // VsTargetFrameworkProvider throws InvalidOperationException in the // some cases (like when targetting packs are missing). In that case // we can't resolve this path. } } } return null; }
public string ResolveAssemblyPath(ProjectId projectId, string assemblyName) { this.AssertIsForeground(); if (_workspace != null) { IVsHierarchy hierarchy; string targetMoniker; if (_workspace.TryGetHierarchy(projectId, out hierarchy) && hierarchy.TryGetProperty((__VSHPROPID)__VSHPROPID4.VSHPROPID_TargetFrameworkMoniker, out targetMoniker) && targetMoniker != null) { try { var frameworkProvider = new VsTargetFrameworkProvider( _workspace.GetVsService <SVsFrameworkMultiTargeting, IVsFrameworkMultiTargeting>(), targetMoniker, _workspace.GetVsService <SVsSmartOpenScope, IVsSmartOpenScope>()); var assembly = frameworkProvider.GetReflectionAssembly(new AssemblyName(assemblyName)); // Codebase specifies where the assembly is on disk. However, it's in // full URI format (i.e. file://c:/...). This will allow us to get the // actual local in the normal path format. Uri uri; if (Uri.TryCreate(assembly.CodeBase, UriKind.RelativeOrAbsolute, out uri)) { return(uri.LocalPath); } } catch (InvalidOperationException) { // VsTargetFrameworkProvider throws InvalidOperationException in the // some cases (like when targetting packs are missing). In that case // we can't resolve this path. } } } return(null); }
// <summary> // Updates app. or web.config to include connection strings, registers the build provider // for WebSite projects and the assembly for WebApp projects // </summary> internal static void UpdateConfig(ModelBuilderSettings settings) { var metadataFileNames = ConnectionManager.GetMetadataFileNamesFromArtifactFileName(settings.Project, settings.ModelPath, PackageManager.Package); if (settings.GenerationOption == ModelGenerationOption.GenerateFromDatabase || settings.GenerationOption == ModelGenerationOption.GenerateDatabaseScript) { if (settings.SaveConnectionStringInAppConfig) { UpdateConfig(metadataFileNames, settings); } } // regardless of GenerationOption we always need to register the build // provider for web site projects and the assembly for web app projects if (settings.VSApplicationType == VisualStudioProjectSystem.Website) { var containingProject = settings.Project; RegisterBuildProvidersInWebConfig(containingProject); // Ensure that System.Data.Entity.Design reference assemblies are added in the web.config. // Get the correct assembly name based on target framework var targetInfo = PackageManager.Package.GetService(typeof(SVsFrameworkMultiTargeting)) as IVsFrameworkMultiTargeting; var openScope = PackageManager.Package.GetService(typeof(SVsSmartOpenScope)) as IVsSmartOpenScope; Debug.Assert(targetInfo != null, "Unable to get IVsFrameworkMultiTargeting from service provider"); if (targetInfo != null && openScope != null) { var targetFrameworkMoniker = VsUtils.GetTargetFrameworkMonikerForProject(containingProject, PackageManager.Package); var provider = new VsTargetFrameworkProvider(targetInfo, targetFrameworkMoniker, openScope); var dataEntityDesignAssembly = provider.GetReflectionAssembly(new AssemblyName("System.Data.Entity.Design")); if (dataEntityDesignAssembly != null) { RegisterAssemblyInWebConfig(containingProject, dataEntityDesignAssembly.FullName); } } } }
private static Assembly TryLoad(VsTargetFrameworkProvider provider, Reference reference) { try { var name = AssemblyName.GetAssemblyName(reference.Path); return provider.GetReflectionAssembly(name); } catch (Exception e) { tracer.Warn(e, Strings.IProjectNodeExtensions.FailedToLoadAssembly(reference.Name, reference.Path)); return null; } }
/// <summary> /// Gets the output assembly of the given project. If the project /// was never built before, it's built before returning the output /// assembly. /// </summary> /// <param name="project">The project to get the output assembly from.</param> /// <param name="buildIfMissing">Whether to build the project if the output assembly is missing.</param> public static Task<Assembly> GetOutputAssembly(this IProjectNode project, bool buildIfMissing = true) { var fileName = (string)project.Properties.TargetFileName; var msBuild = project.Adapt().AsMsBuildProject(); if (msBuild == null) throw new ArgumentException(Strings.IProjectNodeExtensions.NotMsBuildProject(project.DisplayName)); // NOTE: we load from the obj/Debug|Release folder, which is // the one built in the background by VS continuously. var intermediateDir = msBuild.AllEvaluatedProperties .Where(p => p.Name == "IntermediateOutputPath") // If we grab the EvaluatedValue, it won't have the current // global properties overrides, like Configuration and Debug. .Select(p => msBuild.ExpandString(p.UnevaluatedValue)) .FirstOrDefault(); if (string.IsNullOrEmpty(fileName) || string.IsNullOrEmpty(intermediateDir) || string.IsNullOrEmpty(project.Properties.MSBuildProjectDirectory)) { tracer.Warn(Strings.IProjectNodeExtensions.NoTargetAssemblyName(project.DisplayName)); return TaskHelpers.FromResult<Assembly>(null); } var outDir = (string)Path.Combine(project.Properties.MSBuildProjectDirectory, intermediateDir); var assemblyFile = Path.Combine(outDir, fileName); if (!File.Exists(assemblyFile) && !buildIfMissing) return TaskHelpers.FromResult<Assembly>(null); return Task.Factory.StartNew<Assembly>(() => { if (!File.Exists(assemblyFile)) { var success = project.Build().Result; if (success) { // Let the build finish writing the file for (int i = 0; i < 5; i++) { if (File.Exists(assemblyFile)) break; Thread.Sleep(200); } } if (!File.Exists(assemblyFile)) { tracer.Warn(Strings.IProjectNodeExtensions.NoBuildOutput(project.DisplayName, assemblyFile)); return null; } } var assemblyName = AssemblyName.GetAssemblyName(assemblyFile); var vsProject = project.As<IVsHierarchy>(); var localServices = project.As<IServiceProvider>(); var globalServices = GlobalServiceProvider.Instance; if (vsProject == null || localServices == null || globalServices == null) { tracer.Warn(Strings.IProjectNodeExtensions.InvalidVsContext); return null; } var openScope = globalServices.GetService<SVsSmartOpenScope, IVsSmartOpenScope>(); var dtar = localServices.GetService<SVsDesignTimeAssemblyResolution, IVsDesignTimeAssemblyResolution>(); // As suggested by Christy Henriksson, we reuse the type discovery service // but just for the IDesignTimeAssemblyLoader interface. The actual // assembly reading is done by the TFP using metadata only :) var dts = globalServices.GetService<DynamicTypeService>(); var ds = dts.GetTypeDiscoveryService(vsProject); var dtal = ds as IDesignTimeAssemblyLoader; if (openScope == null || dtar == null || dts == null || ds == null || dtal == null) { tracer.Warn(Strings.IProjectNodeExtensions.InvalidTypeContext); return null; } var provider = new VsTargetFrameworkProvider(dtar, dtal, openScope); return provider.GetReflectionAssembly(assemblyName); }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); }
/// <summary> /// Gets the output assembly of the given project. If the project /// was never built before, it's built before returning the output /// assembly. /// </summary> /// <param name="project">The project to get the output assembly from.</param> /// <param name="buildIfMissing">Whether to build the project if the output assembly is missing.</param> public static Task <Assembly> GetOutputAssembly(this IProjectNode project, bool buildIfMissing = true) { var fileName = (string)project.Properties.TargetFileName; var msBuild = project.Adapt().AsMsBuildProject(); if (msBuild == null) { throw new ArgumentException(Strings.IProjectNodeExtensions.NotMsBuildProject(project.DisplayName)); } // NOTE: we load from the obj/Debug|Release folder, which is // the one built in the background by VS continuously. var intermediateDir = msBuild.AllEvaluatedProperties .Where(p => p.Name == "IntermediateOutputPath") // If we grab the EvaluatedValue, it won't have the current // global properties overrides, like Configuration and Debug. .Select(p => msBuild.ExpandString(p.UnevaluatedValue)) .FirstOrDefault(); if (string.IsNullOrEmpty(fileName) || string.IsNullOrEmpty(intermediateDir) || string.IsNullOrEmpty(project.Properties.MSBuildProjectDirectory)) { tracer.Warn(Strings.IProjectNodeExtensions.NoTargetAssemblyName(project.DisplayName)); return(TaskHelpers.FromResult <Assembly>(null)); } var outDir = (string)Path.Combine(project.Properties.MSBuildProjectDirectory, intermediateDir); var assemblyFile = Path.Combine(outDir, fileName); if (!File.Exists(assemblyFile) && !buildIfMissing) { return(TaskHelpers.FromResult <Assembly>(null)); } return(Task.Factory.StartNew <Assembly>(() => { if (!File.Exists(assemblyFile)) { var success = project.Build().Result; if (success) { // Let the build finish writing the file for (int i = 0; i < 5; i++) { if (File.Exists(assemblyFile)) { break; } Thread.Sleep(200); } } if (!File.Exists(assemblyFile)) { tracer.Warn(Strings.IProjectNodeExtensions.NoBuildOutput(project.DisplayName, assemblyFile)); return null; } } var assemblyName = AssemblyName.GetAssemblyName(assemblyFile); var vsProject = project.As <IVsHierarchy>(); var localServices = project.As <IServiceProvider>(); var globalServices = GlobalServiceProvider.Instance; if (vsProject == null || localServices == null || globalServices == null) { tracer.Warn(Strings.IProjectNodeExtensions.InvalidVsContext); return null; } var openScope = globalServices.GetService <SVsSmartOpenScope, IVsSmartOpenScope>(); var dtar = localServices.GetService <SVsDesignTimeAssemblyResolution, IVsDesignTimeAssemblyResolution>(); // As suggested by Christy Henriksson, we reuse the type discovery service // but just for the IDesignTimeAssemblyLoader interface. The actual // assembly reading is done by the TFP using metadata only :) var dts = globalServices.GetService <DynamicTypeService>(); var ds = dts.GetTypeDiscoveryService(vsProject); var dtal = ds as IDesignTimeAssemblyLoader; if (openScope == null || dtar == null || dts == null || ds == null || dtal == null) { tracer.Warn(Strings.IProjectNodeExtensions.InvalidTypeContext); return null; } var provider = new VsTargetFrameworkProvider(dtar, dtal, openScope); return provider.GetReflectionAssembly(assemblyName); }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)); }
private Assembly ResolveAssembly(ProjectId projectId, string assemblyName) { this.AssertIsForeground(); if (_workspace == null) { return null; } if (!_workspace.TryGetHierarchy(projectId, out var hierarchy) || !hierarchy.TryGetProperty((__VSHPROPID)__VSHPROPID4.VSHPROPID_TargetFrameworkMoniker, out string targetMoniker) || targetMoniker == null) { return null; } try { // Below we use the DesignTimeAssemblyResolver functionality of VS to // determine if we can resolve the specified assembly name in the context // of this project. However, this service does not do the right thing // in UWP apps. Specifically, it *will* resolve the assembly to a // reference assembly, even though that's never what we want. In order // to deal with that, we put in this little check where we do not allow // reference assembly resolution if the projects TargetFrameworkMoniker // is ".NETCore, Version=5.0" or greater. var frameworkName = new FrameworkName(targetMoniker); if (StringComparer.OrdinalIgnoreCase.Equals(frameworkName.Identifier, ".NETCore") && frameworkName.Version >= new Version(major: 5, minor: 0)) { return null; } } catch (ArgumentException) { // Something wrong with our TFM. We don't have enough information to // properly resolve this assembly name. return null; } try { var frameworkProvider = new VsTargetFrameworkProvider( _workspace.GetVsService<SVsFrameworkMultiTargeting, IVsFrameworkMultiTargeting>(), targetMoniker, _workspace.GetVsService<SVsSmartOpenScope, IVsSmartOpenScope>()); return frameworkProvider.GetReflectionAssembly(new AssemblyName(assemblyName)); } catch (InvalidOperationException) { // VsTargetFrameworkProvider throws InvalidOperationException in the // some cases (like when targetting packs are missing). In that case // we can't resolve this path. return null; } }