/// <summary>
        ///   Checkout files using Visual Studio shell interop.
        /// </summary>
        /// <param name="filesToCheckOut"></param>
        /// <returns></returns>
        private bool CheckOutFilesThroughShell(object[] filesToCheckOut)
        {
            uint pfEditVerdict;
            uint prgfMoreInfo;

            string[] filesArray = new string[filesToCheckOut.Length];
            IVsQueryEditQuerySave2 queryEditQuerySave = package.GetService(typeof(SVsQueryEditQuerySave)) as IVsQueryEditQuerySave2;

            if (queryEditQuerySave == null)
            {
                return(false);
            }

            for (int i = 0; i < filesToCheckOut.Length; i++)
            {
                filesArray[i] = filesToCheckOut[i].ToString();
            }

            var result = queryEditQuerySave.QueryEditFiles((int)tagVSQueryEditFlags.QEF_SilentMode, filesToCheckOut.Length, filesArray, null, null, out pfEditVerdict, out prgfMoreInfo);

            if (result == VSConstants.S_OK)
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// This function asks to the QueryEditQuerySave service if it is possible to
        /// edit the file.
        /// </summary>
        /// <returns>True if the editing of the file are enabled, otherwise returns false.</returns>
        public bool CanEditFile(string fileName)
        {
            // see: https://github.com/Microsoft/VSSDK-Extensibility-Samples/blob/master/Editor_With_Toolbox/CS/EditorPane.cs

            // Check the status of the recursion guard
            if (gettingCheckoutStatus)
            {
                return(false);
            }

            ThreadHelper.ThrowIfNotOnUIThread();

            try
            {
                // Set the recursion guard
                gettingCheckoutStatus = true;

                // Get the QueryEditQuerySave service
                IVsQueryEditQuerySave2 queryEditQuerySave = package.GetService <SVsQueryEditQuerySave, IVsQueryEditQuerySave2>();

                if (queryEditQuerySave == null)
                {
                    return(false);
                }

                // Now call the QueryEdit method to find the edit status of this file
                string[] documents = { fileName };
                uint     result;
                uint     outFlags;

                // Note that this function can pop up a dialog to ask the user to checkout the file.
                // When this dialog is visible, it is possible to receive other request to change
                // the file and this is the reason for the recursion guard.
                int hr = queryEditQuerySave.QueryEditFiles(
                    0,              // Flags
                    1,              // Number of elements in the array
                    documents,      // Files to edit
                    null,           // Input flags
                    null,           // Input array of VSQEQS_FILE_ATTRIBUTE_DATA
                    out result,     // result of the checkout
                    out outFlags    // Additional flags
                    );

                if (ErrorHandler.Succeeded(hr) && (result == (uint)tagVSQueryEditResult.QER_EditOK))
                {
                    // In this case (and only in this case) we can return true from this function.
                    return(true);
                }
                else
                {
                    Logger.Error($"QueryEditFiles() returned non-ok result ({result})");
                    return(false);
                }
            }
            finally
            {
                gettingCheckoutStatus = false;
            }
        }
Пример #3
0
        /// <summary>
        /// This function asks the QueryEditQuerySave service if it is possible to edit the file.
        /// This can result in an automatic checkout of the file and may even prompt the user for
        /// permission to checkout the file.  If the user says no or the file cannot be edited
        /// this returns false.
        /// </summary>
        private bool CanEditFile()
        {
            // Cache the value so we don't keep asking the user over and over.
            if (_canEditFile.HasValue)
            {
                return((bool)_canEditFile);
            }

            // Check the status of the recursion guard
            if (_gettingCheckoutStatus)
            {
                return(false);
            }

            _canEditFile = false; // assume the worst
            try
            {
                // Set the recursion guard
                _gettingCheckoutStatus = true;

                // Get the QueryEditQuerySave service
                IVsQueryEditQuerySave2 queryEditQuerySave = serviceProvider.GetService(typeof(SVsQueryEditQuerySave)) as IVsQueryEditQuerySave2;

                string filename = xmlModel.Name;

                // Now call the QueryEdit method to find the edit status of this file
                string[] documents = { filename };
                uint     result;
                uint     outFlags;

                // Note that this function can popup a dialog to ask the user to checkout the file.
                // When this dialog is visible, it is possible to receive other request to change
                // the file and this is the reason for the recursion guard
                int hr = queryEditQuerySave.QueryEditFiles(
                    0,              // Flags
                    1,              // Number of elements in the array
                    documents,      // Files to edit
                    null,           // Input flags
                    null,           // Input array of VSQEQS_FILE_ATTRIBUTE_DATA
                    out result,     // result of the checkout
                    out outFlags    // Additional flags
                    );
                if (ErrorHandler.Succeeded(hr) && (result == (uint)tagVSQueryEditResult.QER_EditOK))
                {
                    // In this case (and only in this case) we can return true from this function
                    _canEditFile = true;
                }
            }
            finally
            {
                _gettingCheckoutStatus = false;
            }
            return((bool)_canEditFile);
        }
Пример #4
0
        /// <summary>
        /// This function asks to the QueryEditQuerySave service if it is possible to
        /// edit the file.
        /// </summary>
        protected bool CanEditFile(string documentMoniker)
        {
            XSettings.LogMessage(String.Format(CultureInfo.CurrentCulture, "\t**** CanEditFile called ****"));

            // Check the status of the recursion guard
            if (this.gettingCheckoutStatus)
            {
                return(false);
            }

            try
            {
                // Set the recursion guard
                this.gettingCheckoutStatus = true;
                ThreadHelper.ThrowIfNotOnUIThread();

                // Get the QueryEditQuerySave service
                IVsQueryEditQuerySave2 queryEditQuerySave = (IVsQueryEditQuerySave2)this.projectMgr.GetService(typeof(SVsQueryEditQuerySave));

                // Now call the QueryEdit method to find the edit status of this file
                string[] documents = { documentMoniker };
                uint     result;
                uint     outFlags;

                // Note that this function can popup a dialog to ask the user to checkout the file.
                // When this dialog is visible, it is possible to receive other request to change
                // the file and this is the reason for the recursion guard.
                int hr = queryEditQuerySave.QueryEditFiles(
                    0,              // Flags
                    1,              // Number of elements in the array
                    documents,      // Files to edit
                    null,           // Input flags
                    null,           // Input array of VSQEQS_FILE_ATTRIBUTE_DATA
                    out result,     // result of the checkout
                    out outFlags    // Additional flags
                    );

                if (ErrorHandler.Succeeded(hr) && (result == (uint)tagVSQueryEditResult.QER_EditOK))
                {
                    // In this case (and only in this case) we can return true from this function.
                    return(true);
                }
            }
            finally
            {
                this.gettingCheckoutStatus = false;
            }

            return(false);
        }
Пример #5
0
        /// <summary>
        /// Displays a dialog offering user to select whether he wants to reload the outside-VS changes
        /// </summary>
        public virtual void FileChangedOutsideVS()
        {
            IVsQueryEditQuerySave2 queryEditQuerySave = (IVsQueryEditQuerySave2)GetService(typeof(SVsQueryEditQuerySave));

            // ---Now call the QueryEdit method to find the edit status of this file
            string[] documents = { FileName };
            uint     result;
            uint     outFlags;

            int hr = queryEditQuerySave.QueryEditFiles(
                0,           // Flags
                1,           // Number of elements in the array
                documents,   // Files to edit
                null,        // Input flags
                null,        // Input array of VSQEQS_FILE_ATTRIBUTE_DATA
                out result,  // result of the checkout
                out outFlags // Additional flags
                );

            string message = FileName + Environment.NewLine +
                             Environment.NewLine + "File was changed outside the environment. Do you want to reload it?";

            string     title     = String.Empty;
            IVsUIShell VsUiShell = (IVsUIShell)Package.GetGlobalService(typeof(SVsUIShell));

            int  r        = (int)DialogResult.No;
            Guid tempGuid = Guid.Empty;

            if (VsUiShell != null)
            {
                //Show up a message box indicating that the file has changed outside of VS environment
                VsUiShell.ShowMessageBox(0,
                                         ref tempGuid,
                                         title,
                                         message,
                                         null,
                                         0,
                                         OLEMSGBUTTON.OLEMSGBUTTON_YESNOCANCEL,
                                         OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                                         OLEMSGICON.OLEMSGICON_QUERY,
                                         0,
                                         out r);
            }
            //if the user selects "Yes", reload the current file
            if (r == (int)DialogResult.Yes)
            {
                ((IVsPersistDocData)this).ReloadDocData(0);
            }
        }
        /// <summary>
        /// This function asks to the QueryEditQuerySave service if it is possible to
        /// edit the file.
        /// </summary>
        /// <returns>True if the editing of the file are enabled, otherwise returns false.</returns>
        private bool CanEditFile()
        {
            // Check the status of the recursion guard
            if (gettingCheckoutStatus)
            {
                return(false);
            }

            try
            {
                // Set the recursion guard
                gettingCheckoutStatus = true;

                // Get the QueryEditQuerySave service
                IVsQueryEditQuerySave2 queryEditQuerySave = (IVsQueryEditQuerySave2)GetService(typeof(SVsQueryEditQuerySave));

                // Now call the QueryEdit method to find the edit status of this file
                string[] documents = { this.fileName };
                uint     result;
                uint     outFlags;

                // Note that this function can pop up a dialog to ask the user to checkout the file.
                // When this dialog is visible, it is possible to receive other request to change
                // the file and this is the reason for the recursion guard.
                int hr = queryEditQuerySave.QueryEditFiles(
                    0,              // Flags
                    1,              // Number of elements in the array
                    documents,      // Files to edit
                    null,           // Input flags
                    null,           // Input array of VSQEQS_FILE_ATTRIBUTE_DATA
                    out result,     // result of the checkout
                    out outFlags    // Additional flags
                    );
                if (ErrorHandler.Succeeded(hr) && (result == (uint)tagVSQueryEditResult.QER_EditOK))
                {
                    // In this case (and only in this case) we can return true from this function.
                    return(true);
                }
            }
            finally
            {
                gettingCheckoutStatus = false;
            }
            return(false);
        }
Пример #7
0
        private bool CanEditFile(string filePath)
        {
            if (gettingCheckoutStatus)
            {
                return(false);
            }

            try
            {
                gettingCheckoutStatus = true;

                IVsQueryEditQuerySave2 queryEditQuerySave =
                    (IVsQueryEditQuerySave2)GetService(typeof(SVsQueryEditQuerySave));

                string[] documents = { filePath };
                uint     result;
                uint     outFlags;

                int hr = queryEditQuerySave.QueryEditFiles(
                    0,
                    documents.Length,
                    documents,
                    null,
                    null,
                    out result,
                    out outFlags);

                if (ErrorHandler.Succeeded(hr) && (result ==
                                                   (uint)tagVSQueryEditResult.QER_EditOK))
                {
                    return(true);
                }
            }
            finally
            {
                gettingCheckoutStatus = false;
            }

            return(false);
        }
        public virtual int UpgradeProject(string projectFileName, uint upgradeFlag, string copyLocation, out string upgradeFullyQualifiedFileName, IVsUpgradeLogger logger, out int upgradeRequired,
                                          out Guid newProjectFactory)
        {
            uint ignore;

            this.UpgradeProject_CheckOnly(projectFileName, logger, out upgradeRequired, out newProjectFactory, out ignore);
            if (upgradeRequired == 0)
            {
                upgradeFullyQualifiedFileName = projectFileName;
                return(VSConstants.S_OK);
            }

            string projectName = Path.GetFileNameWithoutExtension(projectFileName);

            upgradeFullyQualifiedFileName = projectFileName;

            // Query for edit
            IVsQueryEditQuerySave2 queryEdit = site.GetService(typeof(SVsQueryEditQuerySave)) as IVsQueryEditQuerySave2;

            if (queryEdit != null)
            {
                uint editVerdict;
                uint queryEditMoreInfo;
                const tagVSQueryEditFlags tagVSQueryEditFlags_QEF_AllowUnopenedProjects = (tagVSQueryEditFlags)0x80;

                int hr = queryEdit.QueryEditFiles(
                    (uint)(tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting | tagVSQueryEditFlags.QEF_DisallowInMemoryEdits | tagVSQueryEditFlags_QEF_AllowUnopenedProjects),
                    1, new[] { projectFileName }, null, null, out editVerdict, out queryEditMoreInfo);
                if (ErrorHandler.Failed(hr))
                {
                    return(VSConstants.E_FAIL);
                }

                if (editVerdict != (uint)tagVSQueryEditResult.QER_EditOK)
                {
                    if (logger != null)
                    {
                        logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, projectName, projectFileName,
                                          SR.GetString(SR.UpgradeCannotOpenProjectFileForEdit));
                    }
                    return(VSConstants.E_FAIL);
                }

                // If file was modified during the checkout, maybe upgrade is not needed
                if ((queryEditMoreInfo & (uint)tagVSQueryEditResultFlags.QER_MaybeChanged) != 0)
                {
                    this.UpgradeProject_CheckOnly(projectFileName, logger, out upgradeRequired, out newProjectFactory, out ignore);
                    if (upgradeRequired == 0)
                    {
                        if (logger != null)
                        {
                            logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, projectFileName,
                                              SR.GetString(SR.UpgradeNoNeedToUpgradeAfterCheckout));
                        }

                        return(VSConstants.S_OK);
                    }
                }
            }

            // Convert the project
            Microsoft.Build.Conversion.ProjectFileConverter projectConverter = new Microsoft.Build.Conversion.ProjectFileConverter();
            projectConverter.OldProjectFile = projectFileName;
            projectConverter.NewProjectFile = projectFileName;
            ProjectRootElement convertedProject = null;

            try
            {
                convertedProject = projectConverter.ConvertInMemory();
            }
            catch (Exception ex)
            {
                if (logger != null)
                {
                    logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, projectName, projectFileName, ex.Message);
                }
            }

            if (convertedProject != null)
            {
                this.m_lastUpgradedProjectFile = projectFileName;
                foreach (ProjectPropertyElement property in convertedProject.Properties)
                {
                    switch (property.Name)
                    {
                    case SCC_LOCAL_PATH:
                        this.m_sccLocalPath = property.Value;
                        break;

                    case SCC_AUX_PATH:
                        this.m_sccAuxPath = property.Value;
                        break;

                    case SCC_PROVIDER:
                        this.m_sccProvider = property.Value;
                        break;

                    case SCC_PROJECT_NAME:
                        this.m_sccProjectName = property.Value;
                        break;

                    default:
                        break;
                    }
                }
                try
                {
                    convertedProject.Save(projectFileName);
                }
                catch (Exception ex)
                {
                    if (logger != null)
                    {
                        logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, projectName, projectFileName, ex.Message);
                    }
                    return(VSConstants.E_FAIL);
                }
                if (logger != null)
                {
                    logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_STATUSMSG, projectName, projectFileName,
                                      SR.GetString(SR.UpgradeSuccessful));
                }
                return(VSConstants.S_OK);
            }

            this.m_lastUpgradedProjectFile = null;
            upgradeFullyQualifiedFileName  = "";
            return(VSConstants.E_FAIL);
        }
Пример #9
0
        public override int UpgradeProject(string fileName, uint upgradeFlag, string copyLocation, out string upgradedFullyQualifiedFileName, IVsUpgradeLogger logger, out int upgradeRequired, out Guid newProjectFactory)
        {
            uint   ignore;
            string projectName = Path.GetFileNameWithoutExtension(fileName);

            upgradedFullyQualifiedFileName = fileName;

            this.UpgradeProject_CheckOnly(fileName, logger, out upgradeRequired, out newProjectFactory, out ignore);
            if (upgradeRequired == 0)
            {
                upgradedFullyQualifiedFileName = fileName;
                return(VSConstants.S_OK);
            }

            IVsQueryEditQuerySave2 queryEditQuerySave = WixHelperMethods.GetService <IVsQueryEditQuerySave2, SVsQueryEditQuerySave>(this.Site);

            int  qef = (int)tagVSQueryEditFlags.QEF_ReportOnly | (int)__VSQueryEditFlags2.QEF_AllowUnopenedProjects;
            uint verdict;
            uint moreInfo;

            string[] files = new string[1];
            files[0] = fileName;

            bool continueUpgrade = false;

            ErrorHandler.ThrowOnFailure(queryEditQuerySave.QueryEditFiles((uint)qef, 1, files, null, null, out verdict, out moreInfo));
            if (verdict == (uint)tagVSQueryEditResult.QER_EditOK)
            {
                continueUpgrade = true;
            }

            if (verdict == (uint)tagVSQueryEditResult.QER_EditNotOK)
            {
                logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, fileName, WixStrings.ReadOnlyFile);
                if ((moreInfo & (uint)tagVSQueryEditResultFlags.QER_ReadOnlyUnderScc) != 0)
                {
                    qef = (int)tagVSQueryEditFlags.QEF_DisallowInMemoryEdits | (int)__VSQueryEditFlags2.QEF_AllowUnopenedProjects | (int)tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting;
                    ErrorHandler.ThrowOnFailure(queryEditQuerySave.QueryEditFiles((uint)qef, 1, files, null, null, out verdict, out moreInfo));
                    if (verdict == (uint)tagVSQueryEditResult.QER_EditOK)
                    {
                        continueUpgrade = true;
                    }
                }

                if (continueUpgrade)
                {
                    logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, fileName, WixStrings.CheckoutSuccess);
                }
                else
                {
                    logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, projectName, fileName, WixStrings.FailedToCheckoutProject);
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, WixStrings.FailedToCheckoutFile, fileName));
                }
            }

            // If file was modified during the checkout, maybe upgrade is not needed
            if ((moreInfo & (uint)tagVSQueryEditResultFlags.QER_MaybeChanged) != 0)
            {
                this.UpgradeProject_CheckOnly(fileName, logger, out upgradeRequired, out newProjectFactory, out ignore);
                if (upgradeRequired == 0)
                {
                    if (logger != null)
                    {
                        logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, fileName, WixStrings.UpgradeNoNeedToUpgradeAfterCheckout);
                    }

                    return(VSConstants.S_OK);
                }
            }

            if (continueUpgrade)
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(fileName);
                xmlDoc.DocumentElement.SetAttribute(WixProjectFileConstants.ToolsVersion, "4.0");

                bool targetsPathUpdated = false;
                foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
                {
                    if (WixProjectFileConstants.PropertyGroup == node.Name)
                    {
                        foreach (XmlNode propertyNode in node.ChildNodes)
                        {
                            if (WixProjectFileConstants.WixTargetsPath == propertyNode.Name)
                            {
                                if (propertyNode.InnerText.Contains("\\Microsoft\\WiX\\v3.0\\"))
                                {
                                    targetsPathUpdated     = true;
                                    propertyNode.InnerText = propertyNode.InnerText.Replace("\\Microsoft\\WiX\\v3.0\\", "\\Microsoft\\WiX\\v3.x\\");
                                }
                                else if (propertyNode.InnerText.Contains("\\Microsoft\\WiX\\v3.5\\"))
                                {
                                    targetsPathUpdated     = true;
                                    propertyNode.InnerText = propertyNode.InnerText.Replace("\\Microsoft\\WiX\\v3.5\\", "\\Microsoft\\WiX\\v3.x\\");
                                }

                                if (propertyNode.InnerText.Contains("\\Wix2010.targets"))
                                {
                                    targetsPathUpdated     = true;
                                    propertyNode.InnerText = propertyNode.InnerText.Replace("\\Wix2010.targets", "\\Wix.targets");
                                }
                            }
                        }
                    }
                }

                if (targetsPathUpdated)
                {
                    logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, fileName, WixStrings.WixTargetsPathUpdated);
                }

                xmlDoc.Save(fileName);
                upgradedFullyQualifiedFileName = fileName;
            }

            return(VSConstants.S_OK);
        }
Пример #10
0
        public virtual int UpgradeProject(
            string projectFilePath,
            uint upgradeFlag,
            string initialCopyLocation,
            out string upgradeFullyQualifiedFileName,
            IVsUpgradeLogger upgradeLogger,
            out int upgradeRequired,
            out Guid newProjectFactory
            )
        {
            // initialize out params in case of failure
            upgradeFullyQualifiedFileName = null;
            upgradeRequired   = 0;
            newProjectFactory = Guid.Empty;

            __VSPPROJECTUPGRADEVIAFACTORYFLAGS flag;
            string copyLocation = initialCopyLocation;
            var    r            = NormalizeUpgradeFlag(upgradeFlag, out flag, ref copyLocation);

            if (r != VSConstants.S_OK)
            {
                return(r);
            }

            string projectName = Path.GetFileNameWithoutExtension(projectFilePath);
            var    logger      = new ProjectUpgradeLogger(upgradeLogger, projectName, projectFilePath);

            uint ignore;

            ((IVsProjectUpgradeViaFactory)this).UpgradeProject_CheckOnly(projectFilePath, upgradeLogger, out upgradeRequired, out newProjectFactory, out ignore);

            // no upgrade required and not 'copy-backup'
            if (upgradeRequired == 0 && !HasCopyBackupFlag(flag))
            {
                //Write an informational message "No upgrade required for project foo"?
                logger.LogInfo(SR.GetString(SR.ProjectConversionNotRequired));
                logger.LogInfo(SR.GetString(SR.ConversionNotRequired));

                upgradeFullyQualifiedFileName = projectFilePath;
                return(VSConstants.S_OK);
            }

            // upgrade is not required but backup may still be needed

            var projectFileName = Path.GetFileName(projectFilePath);

            upgradeFullyQualifiedFileName = projectFilePath;

            if (HasSxSBackupFlag(flag))
            {
                // for SxS call use location near the original file
                copyLocation = Path.GetDirectoryName(projectFilePath);
            }

            // workflow is taken from vsprjfactory.cpp (vsproject\vsproject)
            // 1. convert the project (in-memory)
            // 2. save SCC related info
            // 3. use data stored on step 2 in GetSccInfo calls (during QueryEditFiles)
            // 4. if succeeded - save project on disk
            // F# doesn't use .user file so all related code is skipped
            try
            {
                // load MSBuild project in memory: this will be needed in all cases not depending whether upgrade is required or not
                // we use this project to determine the set of files to copy
                ProjectRootElement convertedProject = ConvertProject(projectFilePath, logger);
                if (convertedProject == null)
                {
                    throw new ProjectUpgradeFailedException();
                }

                // OK, we need upgrade, save SCC info and ask if project file can be edited
                if (upgradeRequired != 0)
                {
                    // 2. save SCC related info
                    this.m_lastUpgradedProjectFile = projectFilePath;
                    foreach (var property in convertedProject.Properties)
                    {
                        switch (property.Name)
                        {
                        case SCC_LOCAL_PATH:
                            this.m_sccLocalPath = property.Value;
                            break;

                        case SCC_AUX_PATH:
                            this.m_sccAuxPath = property.Value;
                            break;

                        case SCC_PROVIDER:
                            this.m_sccProvider = property.Value;
                            break;

                        case SCC_PROJECT_NAME:
                            this.m_sccProjectName = property.Value;
                            break;

                        default:
                            break;
                        }
                    }

                    // 3. Query for edit (this call may query information stored on previous step)
                    IVsQueryEditQuerySave2 queryEdit = site.GetService(typeof(SVsQueryEditQuerySave)) as IVsQueryEditQuerySave2;
                    if (queryEdit != null)
                    {
                        uint editVerdict;
                        uint queryEditMoreInfo;
                        const tagVSQueryEditFlags tagVSQueryEditFlags_QEF_AllowUnopenedProjects = (tagVSQueryEditFlags)0x80;

                        int hr = queryEdit.QueryEditFiles(
                            (uint)(tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting | tagVSQueryEditFlags.QEF_DisallowInMemoryEdits | tagVSQueryEditFlags_QEF_AllowUnopenedProjects),
                            1, new[] { projectFilePath }, null, null, out editVerdict, out queryEditMoreInfo);

                        if (ErrorHandler.Failed(hr))
                        {
                            throw new ProjectUpgradeFailedException();
                        }

                        if (editVerdict != (uint)tagVSQueryEditResult.QER_EditOK)
                        {
                            throw new ProjectUpgradeFailedException(SR.GetString(SR.UpgradeCannotOpenProjectFileForEdit));
                        }

                        // If file was modified during the checkout, maybe upgrade is not needed
                        if ((queryEditMoreInfo & (uint)tagVSQueryEditResultFlags.QER_MaybeChanged) != 0)
                        {
                            ((IVsProjectUpgradeViaFactory)this).UpgradeProject_CheckOnly(projectFilePath, upgradeLogger, out upgradeRequired, out newProjectFactory, out ignore);
                            if (upgradeRequired == 0)
                            {
                                if (logger != null)
                                {
                                    logger.LogInfo(SR.GetString(SR.UpgradeNoNeedToUpgradeAfterCheckout));
                                }

                                return(VSConstants.S_OK);
                            }
                        }
                    }
                }

                // 3.1 copy backup
                BackupProjectFilesIfNeeded(projectFilePath, logger, flag, copyLocation, convertedProject);

                // 4. if we have performed upgrade - save project to disk
                if (upgradeRequired != 0)
                {
                    try
                    {
                        convertedProject.Save(projectFilePath);
                    }
                    catch (Exception ex)
                    {
                        throw new ProjectUpgradeFailedException(ex.Message, ex);
                    }
                }
                // 821083: "Converted" should NOT be localized - it is referenced in the XSLT used to display the UpgradeReport
                logger.LogStatus("Converted");
            }
            catch (ProjectUpgradeFailedException ex)
            {
                var exception = ex.InnerException ?? ex;

                if (exception != null && !string.IsNullOrEmpty(exception.Message))
                {
                    logger.LogError(exception.Message);
                }

                upgradeFullyQualifiedFileName = "";
                m_lastUpgradedProjectFile     = null;
                return(VSConstants.E_FAIL);
            }
            return(VSConstants.S_OK);
        }
        /// <inheritdoc />
        public int UpgradeProject(string bstrFileName, uint fUpgradeFlag, string bstrCopyLocation,
                                  out string pbstrUpgradedFullyQualifiedFileName, IVsUpgradeLogger pLogger, out int pUpgradeRequired,
                                  out Guid pguidNewProjectFactory)
        {
            uint verdict, moreInfo, ignored;

            string[] files = new string[1] {
                bstrFileName
            };
            string projectName     = Path.GetFileNameWithoutExtension(bstrFileName);
            bool   continueUpgrade = false;

            pbstrUpgradedFullyQualifiedFileName = bstrFileName;

            // Be sure we need an upgrade
            this.UpgradeProject_CheckOnly(bstrFileName, pLogger, out pUpgradeRequired, out pguidNewProjectFactory, out ignored);

            if (pUpgradeRequired == 0)
            {
                return(VSConstants.S_OK);
            }

            // See if the file is editable
            IVsQueryEditQuerySave2 qes = Utility.GetServiceFromPackage <IVsQueryEditQuerySave2, SVsQueryEditQuerySave>(true);

            ErrorHandler.ThrowOnFailure(qes.QueryEditFiles((uint)tagVSQueryEditFlags.QEF_ReportOnly |
                                                           (uint)__VSQueryEditFlags2.QEF_AllowUnopenedProjects, 1, files, null, null, out verdict,
                                                           out moreInfo));

            if (verdict == (uint)tagVSQueryEditResult.QER_EditOK)
            {
                continueUpgrade = true;
            }

            if (verdict == (uint)tagVSQueryEditResult.QER_EditNotOK)
            {
                pLogger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, bstrFileName,
                                   "The project file is read-only.  An attempt will be made to check it out if under source control.");

                if ((moreInfo & (uint)tagVSQueryEditResultFlags.QER_ReadOnlyUnderScc) != 0)
                {
                    ErrorHandler.ThrowOnFailure(qes.QueryEditFiles(
                                                    (uint)tagVSQueryEditFlags.QEF_DisallowInMemoryEdits |
                                                    (uint)__VSQueryEditFlags2.QEF_AllowUnopenedProjects |
                                                    (uint)tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting, 1, files, null, null,
                                                    out verdict, out moreInfo));

                    if (verdict == (uint)tagVSQueryEditResult.QER_EditOK)
                    {
                        continueUpgrade = true;
                    }
                }

                if (continueUpgrade)
                {
                    pLogger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, bstrFileName,
                                       "The project file was successfully checked out.");
                }
                else
                {
                    pLogger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, projectName, bstrFileName,
                                       "Unable to check project out of source control.  Upgrade failed.");
                    throw new InvalidOperationException("Unable to check out project file for upgrade: " + bstrFileName);
                }
            }

            // If file was modified during the checkout, confirm that it still needs upgrading
            if ((moreInfo & (uint)tagVSQueryEditResultFlags.QER_MaybeChanged) != 0)
            {
                this.UpgradeProject_CheckOnly(bstrFileName, pLogger, out pUpgradeRequired, out pguidNewProjectFactory, out ignored);

                if (pUpgradeRequired == 0)
                {
                    if (pLogger != null)
                    {
                        pLogger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, bstrFileName,
                                           "The project file was checked out and is already up to date.  No upgrade needed.");
                    }

                    return(VSConstants.S_OK);
                }
            }

            if (continueUpgrade)
            {
                // Make a backup?
                if (fUpgradeFlag == PUVFF_SXSBACKUP)
                {
                    File.Copy(bstrFileName, bstrFileName + ".backup", true);
                }

                // The SancastleProject class contains all the code needed to update the project so all we need
                // to do is load a copy and force it to save a new copy.
                using (SandcastleProject p = new SandcastleProject(bstrFileName, true))
                {
                    p.UpgradeProjectProperties();
                    p.SaveProject(bstrFileName);
                }

                pLogger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, bstrFileName,
                                   "The project file was upgraded successfully.");
            }

            return(VSConstants.S_OK);
        }
        /// <include file='doc\VsCheckoutService.uex' path='docs/doc[@for="VsCheckoutService.CheckoutFile2"]/*' />
        /// <devdoc>
        ///     Checks out the given file, if possible. If the file is already checked out, or
        ///     does not need to be checked out, no Exception is thrown and the function returns.
        ///     This also checks out any additional buffers passed in through the additionalBuffers
        ///     parameter.
        ///     If the file needs be be checked out ot be edited, and it cannot be checked out,
        ///     an exception is thrown.
        ///
        /// </devdoc>
        public virtual void CheckoutFile(string fileName, string[] additionalBuffers)
        {
            EnsureTextManager();
            if (disable)
            {
                return;
            }

            Debug.Assert(textManagerService != null, "Couldn't get text manager service!");
            if (fileName == null)
            {
                throw new ArgumentException(SR.GetString(SR.InvalidArgument, "fileName", "null"));
            }
            if ((!DoesFileNeedCheckout(fileName)) && (additionalBuffers == null || additionalBuffers.Length == 0))
            {
                return;
            }
            bool userCanceled = false;
            bool pSuccess     = false;
            int  errorCode    = 0;

            try{
                IVsQueryEditQuerySave2 qeqs = (IVsQueryEditQuerySave2)serviceProvider.GetService(typeof(SVsQueryEditQuerySave2));

                if (qeqs != null)
                {
                    _VSQueryEditResult editVerdict;

                    string [] files = GetFilesFromHierarchy(fileName, additionalBuffers);
                    if (files.Length == 0)
                    {
                        return;
                    }
                    IntPtr fileMemory = GetWStrArray(files);
                    try {
                        _VSQueryEditResultFlags result = qeqs.QueryEditFiles(0, files.Length, fileMemory, new int[files.Length], 0, out editVerdict);
                        pSuccess = editVerdict == _VSQueryEditResult.QER_EditOK;
                        if (!pSuccess &&
                            ((int)result & (int)_VSQueryEditResultFlags.QER_CheckoutCanceledOrFailed) != 0)
                        {
                            userCanceled = true;
                        }
                    }
                    finally {
                        FreeWStrArray(fileMemory, files.Length);
                    }
                }
                else
                {
                    int result = textManagerService.AttemptToCheckOutBufferFromScc2(fileName, ref pSuccess);
                    if (!pSuccess &&
                        (result & (int)_VSQueryEditResultFlags.QER_CheckoutCanceledOrFailed) != 0)
                    {
                        userCanceled = true;
                    }
                }
            } catch (ExternalException ex) {
                errorCode = ex.ErrorCode;
            }

            if (!pSuccess)
            {
                if (!userCanceled)
                {
                    throw new CheckoutException(SR.GetString(SR.CHECKOUTSERVICEUnableToCheckout), errorCode);
                }
                else
                {
                    throw CheckoutException.Canceled;
                }
            }

            // You can actually configure SSC to edit a read only file, so do not fail the checkout if
            // the file is read only.
            //

            /*
             * if (IsFileReadOnly(fileName)){
             *  Debug.Fail("Checkout returned success, but file is still readonly.  SCC failed to correctly checkout the file.");
             *  throw CheckoutException.Canceled;
             * }
             */
        }
Пример #13
0
        /// <include file='doc\DesignerService.uex' path='docs/doc[@for="DesignerService.IVSMDDesignerService.RegisterDesignViewAttribute"]/*' />
        /// <devdoc>
        ///     This class is called to report the value of the design view attribute on
        ///     a particular class.  It is generally called by a compiler.
        /// </devdoc>
        void IVSMDDesignerService.RegisterDesignViewAttribute(object pHier, int itemid, int cClass, string pwszAttributeValue)
        {
            // Check the attribute container
            //
            if (!(pHier is IVsHierarchy))
            {
                throw new ArgumentException("pHier");
            }

            // If the project file is not checked out, then don't make any changes to the subitem type.
            // We can get called as the compiler rolls through the classes, and we don't want to
            // flip bits in the project system if it is checked into source code control.
            //
            bool saveAttribute = true;

            object obj;
            int    hr = ((IVsHierarchy)pHier).GetProperty(__VSITEMID.VSITEMID_ROOT, __VSHPROPID.VSHPROPID_ExtObject, out obj);

            if (NativeMethods.Succeeded(hr))
            {
                Project project = (Project)obj;

                IVsQueryEditQuerySave2 qeqs = (IVsQueryEditQuerySave2)GetService(typeof(SVsQueryEditQuerySave2));

                if (qeqs != null)
                {
                    string projectFile = project.FileName;
                    IntPtr memBlock    = Marshal.AllocCoTaskMem(IntPtr.Size);
                    Marshal.WriteIntPtr(memBlock, 0, Marshal.StringToCoTaskMemUni(projectFile));

                    try {
                        _VSQueryEditResult      editVerdict;
                        _VSQueryEditResultFlags result = qeqs.QueryEditFiles((int)tagVSQueryEditFlags.QEF_ReportOnly, 1, memBlock, new int[1], 0, out editVerdict);
                        saveAttribute = editVerdict == _VSQueryEditResult.QER_EditOK;
                    }
                    finally {
                        IntPtr str = Marshal.ReadIntPtr(memBlock, 0);
                        Marshal.FreeCoTaskMem(str);
                        Marshal.FreeCoTaskMem(memBlock);
                    }
                }
            }

            AttributeBucket attributeBucket = (AttributeBucket)attributeHash[itemid];

            if (attributeBucket == null)
            {
                attributeBucket       = new AttributeBucket();
                attributeHash[itemid] = attributeBucket;
            }

            // Attribute registration does a number of things. What comes out the
            // other end of attributeBucket, however, is a string containing the
            // best attribute so far.
            attributeBucket.RegisterAttribute(cClass, pwszAttributeValue);

            string bestAttribute = attributeBucket.BestAttribute;

            if (saveAttribute)
            {
                Debug.Assert(pHier != null, "Invalid hierarchy passed to us");
                ((IVsHierarchy)pHier).SetProperty(itemid, __VSHPROPID.VSHPROPID_ItemSubType, bestAttribute);
            }
        }