internal static DesignerErrorList GetSingleDocErrorList(Uri uri) { DesignerErrorList errorList = null; var currentProject = VSHelpers.GetProjectForDocument(uri.LocalPath, PackageManager.Package); if (currentProject != null) { var hierarchy = VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider); if (hierarchy != null) { var fileFinder = new VSFileFinder(uri.LocalPath); fileFinder.FindInProject(hierarchy); Debug.Assert(fileFinder.MatchingFiles.Count <= 1, "Unexpected count of matching files in project"); foreach (var vsFileInfo in fileFinder.MatchingFiles) { if (vsFileInfo.Hierarchy == VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider)) { errorList = GetSingleDocErrorList(vsFileInfo.Hierarchy, vsFileInfo.ItemId); break; } } } } return(errorList); }
internal static ErrorTask CreateErrorTask( string document, string errorMessage, TextSpan textSpan, TaskErrorCategory taskErrorCategory, IVsHierarchy hierarchy, uint itemID, MARKERTYPE markerType) { ErrorTask errorTask = null; IOleServiceProvider oleSp = null; hierarchy.GetSite(out oleSp); IServiceProvider sp = new ServiceProvider(oleSp); // see if Document is open IVsTextLines buffer = null; var docData = VSHelpers.GetDocData(sp, document); if (docData != null) { buffer = VSHelpers.GetVsTextLinesFromDocData(docData); } if (buffer != null) { errorTask = new EFModelDocumentTask(sp, buffer, markerType, textSpan, document, itemID, errorMessage, hierarchy); errorTask.ErrorCategory = taskErrorCategory; } else { errorTask = new EFModelErrorTask( document, errorMessage, textSpan.iStartLine, textSpan.iEndLine, taskErrorCategory, hierarchy, itemID); } return(errorTask); }
// <summary> // Project retargeting event handler. // 1. Check the project type, return immediately if project is misc project or a project that does not support EF. // 2. Find all the EDMX files in the project. Skip Data Services edmx files and linked files. // 3. Sync all the namespaces based on the new target framework // </summary> public void RetargetFilesInProject() { var project = VSHelpers.GetProject(_hierarchy); if (project == null || !VsUtils.EntityFrameworkSupportedInProject(project, _serviceProvider, allowMiscProject: false)) { return; } var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(project, _serviceProvider, useLatestIfNoEF: false); Debug.Assert(targetSchemaVersion != null, "schema version must not be null for projects that support EF"); var documentMap = new Dictionary <string, object>(); foreach (var vsFileInfo in GetEdmxFileInfos()) { try { var projectItem = VsUtils.GetProjectItem(_hierarchy, vsFileInfo.ItemId); // skip the process for astoria edmx file or a linked edmx file if (IsDataServicesEdmx(projectItem.get_FileNames(1)) || VsUtils.IsLinkProjectItem(projectItem)) { continue; } var doc = RetargetFile(vsFileInfo.Path, targetSchemaVersion); if (doc != null) { documentMap.Add(vsFileInfo.Path, doc); } } catch (Exception ex) { // TODO: When there is an exception; should we continue? VsUtils.LogStandardError( string.Format(CultureInfo.CurrentCulture, Resources.ErrorSynchingEdmxNamespaces, vsFileInfo.Path, ex.Message), vsFileInfo.Path, 0, 0); throw; } } WriteModifiedFiles(project, documentMap); }
// <summary> // Return the EF Runtime assemblies path. // </summary> internal static string GetRuntimeAssemblyPath(Project project, IServiceProvider serviceProvider) { // Get Project Design Time Assembly Resolution. // Don't call GetVsHierarchy(project) because it causes dependencies with EDM Package service provider. var hierarchy = VSHelpers.GetVsHierarchy(project, serviceProvider); var dtar = hierarchy as IVsDesignTimeAssemblyResolution; if (dtar != null) { // There is a bug where the first time you call ResolveAssemblyPathInTargetFx, resolvedAssemblyPathCount is 0. // So we are going to try 1 more time if the first call not successful. for (var i = 0; i < 2; i++) { var resolvedAssemblyPath = new VsResolvedAssemblyPath[1]; uint resolvedAssemblyPathCount; if (dtar.ResolveAssemblyPathInTargetFx( new string[1] { "System.Data.Entity" }, 1, resolvedAssemblyPath, out resolvedAssemblyPathCount) == VSConstants.S_OK) { if (resolvedAssemblyPathCount == 1) { return(Path.GetDirectoryName(resolvedAssemblyPath[0].bstrResolvedAssemblyPath)); } } } } else { // Project Design Time Assembly Resolution is not found, try Global Design Time Assembly Resolution. var targetFrameworkMoniker = VsUtils.GetTargetFrameworkMonikerForProject(project, serviceProvider); var multiTargetingService = Services.ServiceProvider.GetService(typeof(SVsFrameworkMultiTargeting)) as IVsFrameworkMultiTargeting; string assemblyPath; if (multiTargetingService.ResolveAssemblyPath("System.Data.Entity", targetFrameworkMoniker, out assemblyPath) == VSConstants.S_OK) { return(Path.GetDirectoryName(assemblyPath)); } } // if we could not resolve the assembly using global or project design time assembly resolution, return string empty. return(String.Empty); }
internal static void SqlDatabaseFileUpgradeService_OnUpgradeProject( IVsHierarchy hierarchy, string databaseFile, string newConnectionString, IVsUpgradeLogger logger) { if (PackageManager.Package != null && PackageManager.Package.ModelManager != null) { var project = VSHelpers.GetProject(hierarchy); // skip the step if it is a miscellaneous project or if the project is using IIS // (projects using IIS should not be upgraded - see bug 812074) if (project != null && !VsUtils.IsMiscellaneousProject(project) && !IsUsingIIS(project)) { // update the config file as needed IDictionary <string, object> documentMap = new Dictionary <string, object>(); var configFilePath = ConnectionManager.GetConfigFilePath(project, false); try { if (false == string.IsNullOrWhiteSpace(configFilePath)) // check config file exists { XmlDocument configXmlDoc; if (ConnectionManager.UpdateSqlDatabaseFileDataSourceInConnectionStrings(configFilePath, out configXmlDoc)) { documentMap.Add(configFilePath, configXmlDoc); } } } catch (Exception ex) { // if there were errors above then do not try to change the files on disk - just log the message and return var errMsg = String.Format( CultureInfo.CurrentCulture, Resources.ErrorDuringSqlDatabaseFileUpgrade, configFilePath, ex.Message); logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, project.Name, configFilePath, errMsg); return; } // Actually update the file here if (documentMap.Count > 0) { VsUtils.WriteCheckoutXmlFilesInProject(documentMap); } } } }
private static EFArtifact GetArtifactForValidation(Uri uri, IVsHierarchy hierarchy, ModelManager modelManager) { IServiceProvider oleServiceProvider = null; var modelListener = PackageManager.Package.ModelChangeEventListener; hierarchy.GetSite(out oleServiceProvider); System.IServiceProvider sp = new ServiceProvider(oleServiceProvider); var escherDocData = VSHelpers.GetDocData(sp, uri.LocalPath) as IEntityDesignDocData; EFArtifact artifact = null; // // If we opened the document with Escher, then use the XmlEditor's xlinq tree // If we opened the document with the xml editor, but not escher, then // we don't want to use the XmlEditor's xlinq tree, because then we would be receiving events when // the document changes, and we currently don't support that. // if (escherDocData != null) { artifact = PackageManager.Package.ModelManager.GetNewOrExistingArtifact( uri, new VSXmlModelProvider(PackageManager.Package, PackageManager.Package)); if (modelListener != null) { modelListener.OnBeforeValidateModel(VSHelpers.GetProject(hierarchy), artifact, true); } } else { if (Path.GetExtension(uri.LocalPath).Equals(EntityDesignArtifact.ExtensionEdmx, StringComparison.OrdinalIgnoreCase)) { // no doc data exists for this document, so load it into a temp model manager that can be disposed of when we're done. // Using the LoaderBasedXmlModelProvider will let us catch XML scanner and parser errors (the xml editor will try to // recover from these, and we won't know that the problem occurred. artifact = modelManager.GetNewOrExistingArtifact(uri, new StandaloneXmlModelProvider(PackageManager.Package)); if (modelListener != null) { modelListener.OnBeforeValidateModel(VSHelpers.GetProject(hierarchy), artifact, true); } } } return(artifact); }
internal static void SqlDatabaseFileUpgradeService_OnUpgradeProject( IVsHierarchy hierarchy, string databaseFile, string newConnectionString, IVsUpgradeLogger logger) { if (PackageManager.Package != null && PackageManager.Package.ModelManager != null) { var project = VSHelpers.GetProject(hierarchy); // skip the step if it is a miscellaneous project or if the project is using IIS // (projects using IIS should not be upgraded - see bug 812074) if (project != null && !VsUtils.IsMiscellaneousProject(project) && !IsUsingIIS(project)) { // update the config file as needed var configFileUtils = new ConfigFileUtils(project, PackageManager.Package); UpdateConfigForSqlDbFileUpgrade(configFileUtils, project, logger); } } }
internal static bool LoadAndValidateFiles(params Uri[] uris) { var filesToValidate = new List <VSFileFinder.VSFileInfo>(); foreach (var uri in uris) { Project project; IVsHierarchy projectHierarchy; uint itemId; bool isDocumentInProject; VSFileFinder.VSFileInfo fileInfo; VSHelpers.GetProjectAndFileInfoForPath( uri.LocalPath, PackageManager.Package, out projectHierarchy, out project, out itemId, out isDocumentInProject); fileInfo.Hierarchy = projectHierarchy; fileInfo.ItemId = itemId; fileInfo.Path = uri.LocalPath; filesToValidate.Add(fileInfo); } return(LoadAndValidateFiles(filesToValidate, doEscherValidation: true, shouldValidateArtifact: a => true)); }
int IVsSolutionEvents.OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved) { if (PackageManager.Package != null && PackageManager.Package.ModelManager != null) { foreach (var fileExtension in VSArtifact.GetVSArtifactFileExtensions()) { // discard all documents in the project being closed foreach (var vsFileInfo in new VSFileFinder(fileExtension).FindInProject(pHierarchy)) { var uri = Utils.FileName2Uri(vsFileInfo.Path); PackageManager.Package.ModelManager.ClearArtifact(uri); } } var project = VSHelpers.GetProject(pHierarchy); if (project != null) { PackageManager.Package.AggregateProjectTypeGuidCache.Remove(project); } } return(VSConstants.S_OK); }
internal static void ClearErrorsForDocAcrossLists(Uri uri) { var currentProject = VSHelpers.GetProjectForDocument(uri.LocalPath, PackageManager.Package); if (currentProject != null) { var hierarchy = VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider); if (hierarchy != null) { var fileFinder = new VSFileFinder(uri.LocalPath); fileFinder.FindInProject(hierarchy); Debug.Assert(fileFinder.MatchingFiles.Count <= 1, "Unexpected count of matching files in project"); foreach (var vsFileInfo in fileFinder.MatchingFiles) { if (vsFileInfo.Hierarchy == hierarchy) { ClearErrorsForDocAcrossLists(vsFileInfo.Hierarchy, vsFileInfo.ItemId); break; } } } } }
internal static void SqlCeUpgradeService_OnUpgradeProject(IVsHierarchy hierarchy, IVsUpgradeLogger logger) { if (PackageManager.Package != null && PackageManager.Package.ModelManager != null) { // since this is about retargeting EDMX files on disk, no need to process other file extensions from any converters var fileFinder = new VSFileFinder(EntityDesignArtifact.ExtensionEdmx); fileFinder.FindInProject(hierarchy); var project = VSHelpers.GetProject(hierarchy); // skip the step if it is a miscellaneous project. if (project != null && !VsUtils.IsMiscellaneousProject(project)) { IDictionary <string, object> documentMap = new Dictionary <string, object>(); foreach (var vsFileInfo in fileFinder.MatchingFiles) { try { var projectItem = VsUtils.GetProjectItem(hierarchy, vsFileInfo.ItemId); // Dev 10 bug 648969: skip the process for astoria edmx file. if (EdmUtils.IsDataServicesEdmx(projectItem.get_FileNames(1))) { continue; } // Check whether project item is a linked item var isLinkItem = VsUtils.IsLinkProjectItem(projectItem); if (!isLinkItem) { var doc = MetadataConverterDriver.SqlCeInstance.Convert(SafeLoadXmlFromPath(vsFileInfo.Path)); if (doc != null) { documentMap.Add(vsFileInfo.Path, doc); } } } catch (Exception ex) { var errMsg = String.Format( CultureInfo.CurrentCulture, Resources.ErrorDuringSqlCeUpgrade, vsFileInfo.Path, ex.Message); logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, project.Name, vsFileInfo.Path, errMsg); return; } } if (documentMap.Count > 0) { VsUtils.WriteCheckoutXmlFilesInProject(documentMap); } // now update the config file as needed var configFileUtils = new ConfigFileUtils(project, PackageManager.Package); try { var configXmlDoc = configFileUtils.LoadConfig(); if (configXmlDoc != null) // check config file exists { if (ConnectionManager.UpdateSqlCeProviderInConnectionStrings(configXmlDoc)) { configFileUtils.SaveConfig(configXmlDoc); } } } catch (Exception ex) { var errMsg = String.Format( CultureInfo.CurrentCulture, Resources.ErrorDuringSqlCeUpgrade, configFileUtils.GetConfigPath(), ex.Message); logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, project.Name, configFileUtils.GetConfigPath(), errMsg); } } } }
internal static void NavigateTo(Object sender, EventArgs arguments) { Debug.Assert(_dslDesignerOnNavigate != null, "DSL navigation delegate is null!"); var task = sender as ErrorTask; if (task == null) { Debug.Fail("unable to cast sender to Task instance"); return; } var efTask = task as IXmlModelErrorTask; if (efTask == null) { Debug.Fail("Unable to cast errorTask to IEFErrorTask"); return; } if (String.IsNullOrEmpty(task.Document)) { return; } var serviceProvider = efTask.ServiceProvider; var docDataObject = VSHelpers.GetDocData(serviceProvider, task.Document); if (docDataObject == null) { // document wasn't opened var uri = Utils.FileName2Uri(task.Document); if (Path.GetExtension(uri.LocalPath) .Equals(EntityDesignArtifact.ExtensionEdmx, StringComparison.OrdinalIgnoreCase)) { // load a temp model to determine if the document is designer safe (only for EDMX, don't do this for converter docs) var isArtifactDesignerSafe = IsUnloadedDocumentDesignerSafe(uri); if (isArtifactDesignerSafe) { // this will open the document in escher EscherDesignerNavigate(serviceProvider, uri, task); } else { // if the document cannot be displayed in the designer, so open it in the XML Editor and navigate to the error var logicalView = VSConstants.LOGVIEWID_Primary; VsShellUtilities.OpenDocumentWithSpecificEditor( serviceProvider, uri.LocalPath, CommonPackageConstants.xmlEditorGuid, logicalView); docDataObject = VSHelpers.GetDocData(serviceProvider, task.Document); Debug.Assert( docDataObject != null, "attempt to open EDMX document in XML Editor - docDataObject should not be null"); VSHelpers.TextBufferNavigateTo( serviceProvider, docDataObject, logicalView, task.Line, task.Column); } } else { // document is not EDMX, so navigate to the document in the docdata's primary editor VsShellUtilities.OpenDocument(serviceProvider, task.Document); docDataObject = VSHelpers.GetDocData(serviceProvider, task.Document); Debug.Assert( docDataObject != null, "attempt to open non-EDMX document with primary Editor - docDataObject should not be null"); VSHelpers.TextBufferNavigateTo( serviceProvider, docDataObject, VSConstants.LOGVIEWID_Primary, task.Line, task.Column); } } else if (docDataObject is IEntityDesignDocData) { // attempt to get the artifact. This will return non-null if the document is open in either XML Editor or the designer var uri = Utils.FileName2Uri(task.Document); var artifact = PackageManager.Package.ModelManager.GetArtifact(uri); if (artifact == null) { Debug.Fail("didn't find artifact for document opened in Escher"); return; } if (artifact.IsDesignerSafe) { // navigate to the correct place in the Escher designer EscherDesignerNavigate(serviceProvider, uri, task); } else { // if the document cannot be displayed in the designer, so open it in the XML Editor and navigate to the error var logicalView = VSConstants.LOGVIEWID_Primary; VsShellUtilities.OpenDocumentWithSpecificEditor( serviceProvider, uri.LocalPath, CommonPackageConstants.xmlEditorGuid, logicalView); docDataObject = VSHelpers.GetDocData(serviceProvider, task.Document); Debug.Assert( docDataObject != null, "EDMX document already open - attempt to open in XML Editor resulted in null docDataObject"); VSHelpers.TextBufferNavigateTo(serviceProvider, docDataObject, logicalView, task.Line, task.Column); } } else { // document is opened, but not in Escher, so navigate to the document in the text editor VSHelpers.TextBufferNavigateTo( serviceProvider, docDataObject, VSConstants.LOGVIEWID_Primary, task.Line, task.Column); } }
public object GetDocData(IServiceProvider site, string documentPath) { return(VSHelpers.GetDocData(site, documentPath)); }