예제 #1
0
        int IVsProjectUpgradeViaFactory.UpgradeProject_CheckOnly(
            string bstrFileName,
            IVsUpgradeLogger pLogger,
            out int pUpgradeRequired,
            out Guid pguidNewProjectFactory,
            out uint pUpgradeProjectCapabilityFlags
            )
        {
            pUpgradeRequired = 0;
            if (!File.Exists(bstrFileName))
            {
                pguidNewProjectFactory         = Guid.Empty;
                pUpgradeProjectCapabilityFlags = 0;
                return(VSConstants.E_INVALIDARG);
            }

            pguidNewProjectFactory = GetType().GUID;

            var backupSupport = __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP;
            var logger = new UpgradeLogger(bstrFileName, pLogger);

            try {
                var projectXml      = ProjectRootElement.Open(bstrFileName);
                var userProjectName = bstrFileName + ".user";
                var userProjectXml  = File.Exists(userProjectName) ? ProjectRootElement.Open(userProjectName) : null;

                var upgradeRequired = UpgradeProjectCheck(
                    projectXml,
                    userProjectXml,
                    logger.Log,
                    ref pguidNewProjectFactory,
                    ref backupSupport
                    );

                if (upgradeRequired != ProjectUpgradeState.NotNeeded)
                {
                    pUpgradeRequired = 1;
                }
            } catch (Exception ex) {
                if (ex.IsCriticalException())
                {
                    throw;
                }
                // Log the error and don't attempt to upgrade the project.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                } catch (InvalidOperationException) {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                pUpgradeRequired = 0;
            }
            pUpgradeProjectCapabilityFlags = (uint)backupSupport;
            return(VSConstants.S_OK);
        }
예제 #2
0
        void IVsProjectUpgradeViaFactory4.UpgradeProject_CheckOnly(
            string bstrFileName,
            IVsUpgradeLogger pLogger,
            out uint pUpgradeRequired,
            out Guid pguidNewProjectFactory,
            out uint pUpgradeProjectCapabilityFlags
            )
        {
            pguidNewProjectFactory = Guid.Empty;

            if (!File.Exists(bstrFileName))
            {
                pUpgradeRequired = 0;
                pUpgradeProjectCapabilityFlags = 0;
                return;
            }

            var backupSupport = __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP;
            var logger = new UpgradeLogger(bstrFileName, pLogger);

            try
            {
                var projectXml      = ProjectRootElement.Open(bstrFileName);
                var userProjectName = bstrFileName + ".user";
                var userProjectXml  = File.Exists(userProjectName) ? ProjectRootElement.Open(userProjectName) : null;

                var upgradeRequired = UpgradeProjectCheck(
                    projectXml,
                    userProjectXml,
                    logger.Log,
                    ref pguidNewProjectFactory,
                    ref backupSupport
                    );

                switch (upgradeRequired)
                {
                case ProjectUpgradeState.SafeRepair:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_SAFEREPAIR;
                    break;

                case ProjectUpgradeState.UnsafeRepair:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_UNSAFEREPAIR;
                    break;

                case ProjectUpgradeState.OneWayUpgrade:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_ONEWAYUPGRADE;
                    break;

                case ProjectUpgradeState.Incompatible:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_INCOMPATIBLE;
                    break;

                case ProjectUpgradeState.Deprecated:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_DEPRECATED;
                    break;

                default:
                case ProjectUpgradeState.NotNeeded:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_NOREPAIR;
                    break;
                }
            }
            catch (Exception ex) when(!ExceptionExtensions.IsCriticalException(ex))
            {
                // Log the error and don't attempt to upgrade the project.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try
                {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                }
                catch (InvalidOperationException)
                {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_NOREPAIR;
            }
            pUpgradeProjectCapabilityFlags = (uint)backupSupport;

            // If the upgrade checker set the factory GUID to ourselves, we need
            // to clear it
            if (pguidNewProjectFactory == GetType().GUID)
            {
                pguidNewProjectFactory = Guid.Empty;
            }
        }
예제 #3
0
        int IVsProjectUpgradeViaFactory.UpgradeProject(
            string bstrFileName,
            uint fUpgradeFlag,
            string bstrCopyLocation,
            out string pbstrUpgradedFullyQualifiedFileName,
            IVsUpgradeLogger pLogger,
            out int pUpgradeRequired,
            out Guid pguidNewProjectFactory
            )
        {
            pbstrUpgradedFullyQualifiedFileName = null;

            // We first run (or re-run) the upgrade check and bail out early if
            // there is actually no need to upgrade.
            var hr = ((IVsProjectUpgradeViaFactory)this).UpgradeProject_CheckOnly(
                bstrFileName,
                pLogger,
                out pUpgradeRequired,
                out pguidNewProjectFactory,
                out var dummy
                );

            if (!ErrorHandler.Succeeded(hr))
            {
                return(hr);
            }

            var logger = new UpgradeLogger(bstrFileName, pLogger);

            var  backup = (__VSPPROJECTUPGRADEVIAFACTORYFLAGS)fUpgradeFlag;
            bool anyBackup, sxsBackup, copyBackup;

            anyBackup = backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED);
            if (anyBackup)
            {
                sxsBackup  = backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP);
                copyBackup = !sxsBackup && backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP);
            }
            else
            {
                sxsBackup = copyBackup = false;
            }

            if (copyBackup)
            {
                throw new NotSupportedException("PUVFF_COPYBACKUP is not supported");
            }

            pbstrUpgradedFullyQualifiedFileName = bstrFileName;

            if (pUpgradeRequired == 0 && !copyBackup)
            {
                // No upgrade required, and no backup required.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, SR.GetString(SR.UpgradeNotRequired));
                return(VSConstants.S_OK);
            }

            try
            {
                UpgradeLogger logger2      = null;
                var           userFileName = bstrFileName + ".user";
                if (File.Exists(userFileName))
                {
                    logger2 = new UpgradeLogger(userFileName, pLogger);
                }
                else
                {
                    userFileName = null;
                }

                if (sxsBackup)
                {
                    // For SxS backups we want to put the old project file alongside
                    // the current one.
                    bstrCopyLocation = Path.GetDirectoryName(bstrFileName);
                }

                if (anyBackup)
                {
                    var namePart          = Path.GetFileNameWithoutExtension(bstrFileName);
                    var extPart           = Path.GetExtension(bstrFileName) + (sxsBackup ? ".old" : "");
                    var projectFileBackup = Path.Combine(bstrCopyLocation, namePart + extPart);
                    for (var i = 1; File.Exists(projectFileBackup); ++i)
                    {
                        projectFileBackup = Path.Combine(
                            bstrCopyLocation,
                            string.Format("{0}{1}{2}", namePart, i, extPart)
                            );
                    }

                    File.Copy(bstrFileName, projectFileBackup);

                    // Back up the .user file if there is one
                    if (userFileName != null)
                    {
                        if (sxsBackup)
                        {
                            File.Copy(
                                userFileName,
                                Path.ChangeExtension(projectFileBackup, ".user.old")
                                );
                        }
                        else
                        {
                            File.Copy(userFileName, projectFileBackup + ".old");
                        }
                    }

                    // TODO: Implement support for backing up all files
                    //if (copyBackup) {
                    //  - Open the project
                    //  - Inspect all Items
                    //  - Copy those items that are referenced relative to the
                    //    project file into bstrCopyLocation
                    //}
                }

                if (this.site.GetService(typeof(SVsQueryEditQuerySave)) is IVsQueryEditQuerySave2 queryEdit)
                {
                    var tagVSQueryEditFlags_QEF_AllowUnopenedProjects = (tagVSQueryEditFlags)0x80;

                    ErrorHandler.ThrowOnFailure(queryEdit.QueryEditFiles(
                                                    (uint)(tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting |
                                                           tagVSQueryEditFlags.QEF_DisallowInMemoryEdits |
                                                           tagVSQueryEditFlags_QEF_AllowUnopenedProjects),
                                                    1,
                                                    new[] { bstrFileName },
                                                    null,
                                                    null,
                                                    out var editVerdict,
                                                    out var queryEditMoreInfo
                                                    ));

                    if (editVerdict != (uint)tagVSQueryEditResult.QER_EditOK)
                    {
                        logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UpgradeCannotCheckOutProject));
                        return(VSConstants.E_FAIL);
                    }

                    // File may have been updated during checkout, so check
                    // again whether we need to upgrade.
                    if ((queryEditMoreInfo & (uint)tagVSQueryEditResultFlags.QER_MaybeChanged) != 0)
                    {
                        hr = ((IVsProjectUpgradeViaFactory)this).UpgradeProject_CheckOnly(
                            bstrFileName,
                            pLogger,
                            out pUpgradeRequired,
                            out pguidNewProjectFactory,
                            out dummy
                            );

                        if (!ErrorHandler.Succeeded(hr))
                        {
                            return(hr);
                        }
                        if (pUpgradeRequired == 0)
                        {
                            logger.Log(__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, SR.GetString(SR.UpgradeNotRequired));
                            return(VSConstants.S_OK);
                        }
                    }
                }

                // Load the project file and user file into MSBuild as plain
                // XML to make it easier for subclasses.
                var projectXml = ProjectRootElement.Open(bstrFileName);
                if (projectXml == null)
                {
                    throw new Exception(SR.GetString(SR.UpgradeCannotLoadProject));
                }

                var userXml = userFileName != null?ProjectRootElement.Open(userFileName) : null;

                // Invoke our virtual UpgradeProject function. If it fails, it
                // will throw and we will log the exception.
                UpgradeProject(ref projectXml, ref userXml, logger.Log);

                // Get the SCC info from the project file.
                if (projectXml != null)
                {
                    this._cachedSccProject     = bstrFileName;
                    this._cachedSccProjectName = string.Empty;
                    this._cachedSccAuxPath     = string.Empty;
                    this._cachedSccLocalPath   = string.Empty;
                    this._cachedSccProvider    = string.Empty;
                    foreach (var property in projectXml.Properties)
                    {
                        switch (property.Name)
                        {
                        case ProjectFileConstants.SccProjectName:
                            this._cachedSccProjectName = property.Value;
                            break;

                        case ProjectFileConstants.SccAuxPath:
                            this._cachedSccAuxPath = property.Value;
                            break;

                        case ProjectFileConstants.SccLocalPath:
                            this._cachedSccLocalPath = property.Value;
                            break;

                        case ProjectFileConstants.SccProvider:
                            this._cachedSccProvider = property.Value;
                            break;

                        default:
                            break;
                        }
                    }
                }

                // Save the updated files.
                if (projectXml != null)
                {
                    projectXml.Save();
                }
                if (userXml != null)
                {
                    userXml.Save();
                }

                // Need to add "Converted" (unlocalized) to the report because
                // the XSLT refers to it.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_STATUSMSG, "Converted");
                return(VSConstants.S_OK);
            }
            catch (Exception ex) when(!ExceptionExtensions.IsCriticalException(ex))
            {
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try
                {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                }
                catch (InvalidOperationException)
                {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                return(VSConstants.E_FAIL);
            }
        }
예제 #4
0
        void IVsProjectUpgradeViaFactory4.UpgradeProject_CheckOnly(
            string bstrFileName,
            IVsUpgradeLogger pLogger,
            out uint pUpgradeRequired,
            out Guid pguidNewProjectFactory,
            out uint pUpgradeProjectCapabilityFlags
        ) {
            pguidNewProjectFactory = Guid.Empty;

            if (!File.Exists(bstrFileName)) {
                pUpgradeRequired = 0;
                pUpgradeProjectCapabilityFlags = 0;
                return;
            }

            var backupSupport = __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED |
                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP |
                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP;
            var logger = new UpgradeLogger(bstrFileName, pLogger);
            try {
                var projectXml = ProjectRootElement.Open(bstrFileName);
                var userProjectName = bstrFileName + ".user";
                var userProjectXml = File.Exists(userProjectName) ? ProjectRootElement.Open(userProjectName) : null;

                var upgradeRequired = UpgradeProjectCheck(
                    projectXml,
                    userProjectXml,
                    logger.Log,
                    ref pguidNewProjectFactory,
                    ref backupSupport
                );

                switch (upgradeRequired) {
                    case ProjectUpgradeState.SafeRepair:
                        pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_SAFEREPAIR;
                        break;
                    case ProjectUpgradeState.UnsafeRepair:
                        pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_UNSAFEREPAIR;
                        break;
                    case ProjectUpgradeState.OneWayUpgrade:
                        pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_ONEWAYUPGRADE;
                        break;
                    case ProjectUpgradeState.Incompatible:
                        pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_INCOMPATIBLE;
                        break;
                    case ProjectUpgradeState.Deprecated:
                        pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_DEPRECATED;
                        break;
                    default:
                    case ProjectUpgradeState.NotNeeded:
                        pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_NOREPAIR;
                        break;
                }

            } catch (Exception ex) {
                if (ex.IsCriticalException()) {
                    throw;
                }
                // Log the error and don't attempt to upgrade the project.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                } catch (InvalidOperationException) {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_NOREPAIR;
            }
            pUpgradeProjectCapabilityFlags = (uint)backupSupport;

            // If the upgrade checker set the factory GUID to ourselves, we need
            // to clear it
            if (pguidNewProjectFactory == GetType().GUID) {
                pguidNewProjectFactory = Guid.Empty;
            }
        }
예제 #5
0
        int IVsProjectUpgradeViaFactory.UpgradeProject_CheckOnly(
            string bstrFileName,
            IVsUpgradeLogger pLogger,
            out int pUpgradeRequired,
            out Guid pguidNewProjectFactory,
            out uint pUpgradeProjectCapabilityFlags
        ) {
            pUpgradeRequired = 0;
            pguidNewProjectFactory = Guid.Empty;

            if (!File.Exists(bstrFileName)) {
                pUpgradeProjectCapabilityFlags = 0;
                return VSConstants.E_INVALIDARG;
            }


            var backupSupport = __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED |
                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP |
                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP;
            var logger = new UpgradeLogger(bstrFileName, pLogger);
            try {
                var projectXml = ProjectRootElement.Open(bstrFileName);
                var userProjectName = bstrFileName + ".user";
                var userProjectXml = File.Exists(userProjectName) ? ProjectRootElement.Open(userProjectName) : null;

                var upgradeRequired = UpgradeProjectCheck(
                    projectXml,
                    userProjectXml,
                    logger.Log,
                    ref pguidNewProjectFactory,
                    ref backupSupport
                );

                if (upgradeRequired != ProjectUpgradeState.NotNeeded) {
                    pUpgradeRequired = 1;
                }
            } catch (Exception ex) {
                if (ex.IsCriticalException()) {
                    throw;
                }
                // Log the error and don't attempt to upgrade the project.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                } catch (InvalidOperationException) {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                pUpgradeRequired = 0;
            }
            pUpgradeProjectCapabilityFlags = (uint)backupSupport;

            // If the upgrade checker set the factory GUID to ourselves, we need
            // to clear it
            if (pguidNewProjectFactory == GetType().GUID) {
                pguidNewProjectFactory = Guid.Empty;
            }

            return VSConstants.S_OK;
        }
예제 #6
0
        int IVsProjectUpgradeViaFactory.UpgradeProject(
            string bstrFileName,
            uint fUpgradeFlag,
            string bstrCopyLocation,
            out string pbstrUpgradedFullyQualifiedFileName,
            IVsUpgradeLogger pLogger,
            out int pUpgradeRequired,
            out Guid pguidNewProjectFactory
        ) {
            pbstrUpgradedFullyQualifiedFileName = null;

            // We first run (or re-run) the upgrade check and bail out early if
            // there is actually no need to upgrade.
            uint dummy;
            var hr = ((IVsProjectUpgradeViaFactory)this).UpgradeProject_CheckOnly(
                bstrFileName,
                pLogger,
                out pUpgradeRequired,
                out pguidNewProjectFactory,
                out dummy
            );

            if (!ErrorHandler.Succeeded(hr)) {
                return hr;
            }

            var logger = new UpgradeLogger(bstrFileName, pLogger);

            var backup = (__VSPPROJECTUPGRADEVIAFACTORYFLAGS)fUpgradeFlag;
            bool anyBackup, sxsBackup, copyBackup;
            anyBackup = backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED);
            if (anyBackup) {
                sxsBackup = backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP);
                copyBackup = !sxsBackup && backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP);
            } else {
                sxsBackup = copyBackup = false;
            }

            if (copyBackup) {
                throw new NotSupportedException("PUVFF_COPYBACKUP is not supported");
            }

            pbstrUpgradedFullyQualifiedFileName = bstrFileName;

            if (pUpgradeRequired == 0 && !copyBackup) {
                // No upgrade required, and no backup required.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, SR.GetString(SR.UpgradeNotRequired));
                return VSConstants.S_OK;
            }

            try {
                UpgradeLogger logger2 = null;
                var userFileName = bstrFileName + ".user";
                if (File.Exists(userFileName)) {
                    logger2 = new UpgradeLogger(userFileName, pLogger);
                } else {
                    userFileName = null;
                }

                if (sxsBackup) {
                    // For SxS backups we want to put the old project file alongside
                    // the current one.
                    bstrCopyLocation = Path.GetDirectoryName(bstrFileName);
                }

                if (anyBackup) {
                    var namePart = Path.GetFileNameWithoutExtension(bstrFileName);
                    var extPart = Path.GetExtension(bstrFileName) + (sxsBackup ? ".old" : "");
                    var projectFileBackup = Path.Combine(bstrCopyLocation, namePart + extPart);
                    for (int i = 1; File.Exists(projectFileBackup); ++i) {
                        projectFileBackup = Path.Combine(
                            bstrCopyLocation,
                            string.Format("{0}{1}{2}", namePart, i, extPart)
                        );
                    }

                    File.Copy(bstrFileName, projectFileBackup);

                    // Back up the .user file if there is one
                    if (userFileName != null) {
                        if (sxsBackup) {
                            File.Copy(
                                userFileName,
                                Path.ChangeExtension(projectFileBackup, ".user.old")
                            );
                        } else {
                            File.Copy(userFileName, projectFileBackup + ".old");
                        }
                    }

                    // TODO: Implement support for backing up all files
                    //if (copyBackup) {
                    //  - Open the project
                    //  - Inspect all Items
                    //  - Copy those items that are referenced relative to the
                    //    project file into bstrCopyLocation
                    //}
                }


                var queryEdit = site.GetService(typeof(SVsQueryEditQuerySave)) as IVsQueryEditQuerySave2;
                if (queryEdit != null) {
                    uint editVerdict;
                    uint queryEditMoreInfo;
                    var tagVSQueryEditFlags_QEF_AllowUnopenedProjects = (tagVSQueryEditFlags)0x80;

                    ErrorHandler.ThrowOnFailure(queryEdit.QueryEditFiles(
                        (uint)(tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting |
                            tagVSQueryEditFlags.QEF_DisallowInMemoryEdits |
                            tagVSQueryEditFlags_QEF_AllowUnopenedProjects),
                        1,
                        new[] { bstrFileName },
                        null,
                        null,
                        out editVerdict,
                        out queryEditMoreInfo
                    ));

                    if (editVerdict != (uint)tagVSQueryEditResult.QER_EditOK) {
                        logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UpgradeCannotCheckOutProject));
                        return VSConstants.E_FAIL;
                    }

                    // File may have been updated during checkout, so check
                    // again whether we need to upgrade.
                    if ((queryEditMoreInfo & (uint)tagVSQueryEditResultFlags.QER_MaybeChanged) != 0) {
                        hr = ((IVsProjectUpgradeViaFactory)this).UpgradeProject_CheckOnly(
                            bstrFileName,
                            pLogger,
                            out pUpgradeRequired,
                            out pguidNewProjectFactory,
                            out dummy
                        );

                        if (!ErrorHandler.Succeeded(hr)) {
                            return hr;
                        }
                        if (pUpgradeRequired == 0) {
                            logger.Log(__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, SR.GetString(SR.UpgradeNotRequired));
                            return VSConstants.S_OK;
                        }
                    }
                }

                // Load the project file and user file into MSBuild as plain
                // XML to make it easier for subclasses.
                var projectXml = ProjectRootElement.Open(bstrFileName);
                if (projectXml == null) {
                    throw new Exception(SR.GetString(SR.UpgradeCannotLoadProject));
                }

                var userXml = userFileName != null ? ProjectRootElement.Open(userFileName) : null;

                // Invoke our virtual UpgradeProject function. If it fails, it
                // will throw and we will log the exception.
                UpgradeProject(ref projectXml, ref userXml, logger.Log);

                // Get the SCC info from the project file.
                if (projectXml != null) {
                    _cachedSccProject = bstrFileName;
                    _cachedSccProjectName = string.Empty;
                    _cachedSccAuxPath = string.Empty;
                    _cachedSccLocalPath = string.Empty;
                    _cachedSccProvider = string.Empty;
                    foreach (var property in projectXml.Properties) {
                        switch (property.Name) {
                            case ProjectFileConstants.SccProjectName:
                                _cachedSccProjectName = property.Value;
                                break;
                            case ProjectFileConstants.SccAuxPath:
                                _cachedSccAuxPath = property.Value;
                                break;
                            case ProjectFileConstants.SccLocalPath:
                                _cachedSccLocalPath = property.Value;
                                break;
                            case ProjectFileConstants.SccProvider:
                                _cachedSccProvider = property.Value;
                                break;
                            default:
                                break;
                        }
                    }
                }

                // Save the updated files.
                if (projectXml != null) {
                    projectXml.Save();
                }
                if (userXml != null) {
                    userXml.Save();
                }

                // Need to add "Converted" (unlocalized) to the report because
                // the XSLT refers to it.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_STATUSMSG, "Converted");
                return VSConstants.S_OK;
            } catch (Exception ex) {
                if (ex.IsCriticalException()) {
                    throw;
                }

                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                } catch (InvalidOperationException) {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                return VSConstants.E_FAIL;
            }
        }
예제 #7
0
        int IVsProjectUpgradeViaFactory.UpgradeProject_CheckOnly(
            string bstrFileName,
            IVsUpgradeLogger pLogger,
            out int pUpgradeRequired,
            out Guid pguidNewProjectFactory,
            out uint pUpgradeProjectCapabilityFlags
            )
        {
            pUpgradeRequired       = 0;
            pguidNewProjectFactory = Guid.Empty;

            if (!File.Exists(bstrFileName))
            {
                pUpgradeProjectCapabilityFlags = 0;
                return(VSConstants.E_INVALIDARG);
            }


            var backupSupport = __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP;
            var logger = new UpgradeLogger(bstrFileName, pLogger);

            try {
                var projectXml      = ProjectRootElement.Open(bstrFileName);
                var userProjectName = bstrFileName + ".user";
                var userProjectXml  = File.Exists(userProjectName) ? ProjectRootElement.Open(userProjectName) : null;

                var upgradeRequired = UpgradeProjectCheck(
                    projectXml,
                    userProjectXml,
                    logger.Log,
                    ref pguidNewProjectFactory,
                    ref backupSupport
                    );

                if (upgradeRequired != ProjectUpgradeState.NotNeeded)
                {
                    pUpgradeRequired = 1;
                }
            } catch (Exception ex) {
                if (ex.IsCriticalException())
                {
                    throw;
                }
                // Log the error and don't attempt to upgrade the project.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                CommonUtils.ActivityLogError(GetType().FullName, ex.ToString());
                pUpgradeRequired = 0;
            }
            pUpgradeProjectCapabilityFlags = (uint)backupSupport;

            // If the upgrade checker set the factory GUID to ourselves, we need
            // to clear it
            if (pguidNewProjectFactory == GetType().GUID)
            {
                pguidNewProjectFactory = Guid.Empty;
            }

            return(VSConstants.S_OK);
        }