Actualización de proyectos
Los cambios en el modelo de proyecto de una versión de Visual Studio a la siguiente pueden requerir la actualización de los proyectos y soluciones para poder ejecutarlos en la versión más reciente. El SDK de Visual Studio proporciona interfaces que se pueden utilizar para implementar la compatibilidad con la actualización en sus propios proyectos.
Estrategias de actualización
A fin de ofrecer soporte para una actualización, la implementación del sistema del proyecto debe definir e implementar una estrategia de actualización. Para determinar dicha estrategia, puede optar por admitir copias de seguridad en paralelo (SxS), copias de seguridad de copia o ambas.
La copia de seguridad SxS significa que un proyecto copia solo los archivos que necesitan actualizarse, agregando un sufijo de nombre de archivo según corresponda, como, por ejemplo, ".old".
Copia de seguridad copia significa que un proyecto copia todos los elementos del proyecto en una ubicación de copia de seguridad proporcionada por el usuario. A continuación, se actualizan los archivos pertinentes en la ubicación original del proyecto.
Cómo funciona la actualización
Cuando se abre una solución creada en una versión anterior de Visual Studio en una versión más reciente, el IDE comprueba el archivo de solución para determinar si necesita una actualización. Si se requiere la actualización, el asistente de actualización se inicia automáticamente para guiar al usuario a través del proceso de actualización.
Cuando una solución necesita actualizarse, consulta la estrategia de actualización a cada generador de proyectos. La estrategia determinará si el generador de proyectos admite la copia de seguridad de copia o la copia de seguridad SxS. Esta información se envía al asistente de actualización, el cual recopila la información necesaria para la copia de seguridad y presenta las opciones aplicables al usuario.
Soluciones de varios proyectos
Si una solución contiene varios proyectos y las estrategias de actualización difieren, como en el caso de un proyecto de C++ que solo admite la copia de seguridad SxS y un proyecto web que solo admite la copia de seguridad de copia, los generadores de proyectos deben negociar la estrategia de actualización.
La solución consulta a cada generador de proyectos su IVsProjectUpgradeViaFactory. A continuación, llama a UpgradeProject_CheckOnly para ver si los archivos de proyecto globales necesitan actualizarse y determinar las estrategias de actualización admitidas. A continuación, se invoca al asistente de actualización.
Cuando el usuario complete el asistente, se llama a UpgradeProject en cada generador de proyectos para realizar la actualización real. Para facilitar la copia de seguridad, los métodos IVsProjectUpgradeViaFactory proporcionan el servicio SVsUpgradeLogger para registrar los detalles del proceso de actualización. Este servicio no se puede almacenar en caché.
Tras actualizar todos los archivos globales pertinentes, cada generador de proyectos puede elegir si creará instancias de un proyecto. La implementación del proyecto debe admitir IVsProjectUpgrade. A continuación se llama al método UpgradeProject para actualizar todos los elementos de proyecto pertinentes.
Nota:
El método UpgradeProject no proporciona el servicio SVsUpgradeLogger. Este servicio se puede obtener llamando a QueryService.
Procedimientos recomendados
Use el servicio SVsQueryEditQuerySave para comprobar si puede editar un archivo antes de proceder a editarlo y si se puede guardar antes de guardarlo. Esto ayudará a las implementaciones de copia de seguridad y actualización a manipular correctamente los archivos de proyecto bajo control de código fuente, los archivos con permisos insuficientes, etc.
Use el servicio SVsUpgradeLogger durante todas las fases de copia de seguridad y actualización para proporcionar información sobre el éxito o error del proceso de actualización.
Para obtener más información sobre la copia de seguridad y la actualización de proyectos, vea los comentarios de IVsProjectUpgrade en vsshell2.idl.
Actualizar proyectos personalizados
Si cambia la información guardada en el archivo del proyecto entre diferentes versiones de Visual Studio de su producto, deberá admitir la actualización del archivo del proyecto de la versión anterior a la nueva. Para admitir una actualización que le permita participar en el asistente para conversión de Visual Studio, implemente la interfaz IVsProjectUpgradeViaFactory. Esta interfaz contiene el único mecanismo disponible para la actualización de la copia. La actualización del proyecto se produce como parte de la apertura de la solución. El generador de proyectos implementa la interfaz IVsProjectUpgradeViaFactory o esta debe poderse obtener como mínimo desde el generador de proyectos.
El mecanismo anterior que usa la interfaz IVsProjectUpgrade sigue siendo compatible, pero conceptualmente actualiza el sistema del proyecto como parte de la apertura de la solución. Por lo tanto, el entorno de Visual Studio llama a la interfaz IVsProjectUpgrade, aunque se implemente o se llame a la interfaz IVsProjectUpgradeViaFactory. Este enfoque le permite usar IVsProjectUpgradeViaFactory para implementar la copia y solo proyectar partes de la actualización, y delegar el resto del trabajo para que lo realice la interfaz IVsProjectUpgrade localmente (posiblemente en la nueva ubicación).
Para obtener una implementación de ejemplo de IVsProjectUpgrade, consulte Ejemplos de VSSDK.
Con las actualizaciones del proyecto, se producen los escenarios siguientes:
Si el archivo tiene un formato más reciente de los que puede admitir el proyecto, debe devolver un error en que se indique esto. Se supone que la versión anterior del producto incluye código para comprobar la versión.
Si se especifica la marca PUVFF_SXSBACKUP en el método UpgradeProject, la actualización se implementará como una actualización local antes de la apertura del proyecto.
Si se especifica la marca PUVFF_COPYBACKUP en el método UpgradeProject, la actualización se implementa como una actualización de copia.
Si se especifica la marca UPF_SILENTMIGRATE en la llamada UpgradeProject, significa que el entorno ha solicitado al usuario que actualice el archivo del proyecto como una actualización local, una vez abierto el proyecto. Por ejemplo, el entorno pide al usuario que realice la actualización cuando este abra una versión anterior de la solución.
Si no se especifica la marca UPF_SILENTMIGRATE en la llamada UpgradeProject, significa que debe solicitar al usuario que actualice el archivo del proyecto.
A continuación, se muestra un ejemplo del mensaje de solicitud de actualización:
"El proyecto '%1' se creó con una versión anterior de Visual Studio. Si lo abre con esta versión de Visual Studio, es posible que no pueda abrirlo con versiones anteriores de Visual Studio. ¿Quiere continuar y abrir este proyecto?"
Para implementar IVsProjectUpgradeViaFactory
Implemente el método de la interfaz IVsProjectUpgradeViaFactory, específicamente el método UpgradeProject de su implementación del generador de proyectos, o realice implementaciones que puedan llamarse desde su implementación del generador de proyectos.
Si quiere realizar una actualización local como parte de la apertura de la solución, proporcione la marca PUVFF_SXSBACKUP como el parámetro
VSPUVF_FLAGS
de su implementación UpgradeProject.Si quiere realizar una actualización local como parte de la apertura de la solución, proporcione la marca PUVFF_COPYBACKUP como el parámetro
VSPUVF_FLAGS
de su implementación UpgradeProject.En relación con los pasos 2 y 3, los pasos de actualización del archivo real mediante IVsQueryEditQuerySave2 se pueden implementar según se describe en la sección "Implementación de
IVsProjectUpgade
", o bien puede delegar la actualización del archivo real a IVsProjectUpgrade.Use los métodos de IVsUpgradeLogger para publicar mensajes relacionados con la actualización para el usuario que usa el Asistente para migración de Visual Studio.
La interfaz IVsFileUpgrade se utiliza para implementar cualquier tipo de actualización de archivo que se debe ejecutar como parte de la actualización del proyecto. Esta interfaz no se llama desde IVsProjectUpgradeViaFactory, sino que se proporciona como un mecanismo para actualizar los archivos que forman parte del sistema del proyecto, pero que puede que el sistema del proyecto principal no tenga en cuenta directamente. Por ejemplo, esta situación podría producirse si el equipo de desarrollo que administra el resto del sistema del proyecto no administra las propiedades y los archivos relacionados con el compilador.
Implementación de IVsProjectUpgrade
Si el sistema del proyecto solo implementa IVsProjectUpgrade, no puede participar en el asistente para conversión de Visual Studio. Sin embargo, aunque implemente la interfaz IVsProjectUpgradeViaFactory, puede agregar de todos modos la actualización del archivo a la implementación IVsProjectUpgrade.
Para implementar IVsProjectUpgrade
Cuando un usuario intenta abrir un proyecto, el entorno llama al método UpgradeProject después de abrir el proyecto y antes de que se pueda realizar ninguna otra acción de usuario en el proyecto. Si ya se había solicitado al usuario que actualizara la solución, la marca UPF_SILENTMIGRATE se pasa al parámetro
grfUpgradeFlags
. Si el usuario abre un proyecto directamente, como cuando utiliza el comando Agregar proyecto existente, la marca UPF_SILENTMIGRATE no se pasa y el proyecto debe solicitar una actualización al usuario.En respuesta a la llamada UpgradeProject, el proyecto debe evaluar si se actualiza el archivo del proyecto. Si el proyecto no necesita actualizar el tipo de proyecto a una nueva versión, simplemente puede devolver la marca S_OK.
Si el proyecto necesita actualizar el tipo de proyecto a una nueva versión, debe determinar si el archivo del proyecto se puede modificar mediante una llamada al método QueryEditFiles y pasando un valor de tagVSQueryEditFlags para el parámetro
rgfQueryEdit
. A continuación, el proyecto debe hacer lo siguiente:Si el valor
VSQueryEditResult
devuelto en el parámetropfEditCanceled
es QER_EditOK, la actualización puede continuar porque se puede escribir en el archivo del proyecto.Si el valor
VSQueryEditResult
devuelto en el parámetropfEditCanceled
es QER_EditNotOK y el valorVSQueryEditResult
tiene el bit QER_ReadOnlyNotUnderScc establecido, UpgradeProject debe devolver un error, ya que los usuarios deben resolver el problema de permisos. A continuación, el proyecto debe hacer lo siguiente:Notifique el error al usuario llamando a ReportErrorInfo y devolviendo el código de error VS_E_PROJECTMIGRATIONFAILED a IVsProjectUpgrade.
Si el valor
VSQueryEditResult
es QER_EditNotOK y el valorVSQueryEditResultFlags
tiene el bit QER_ReadOnlyUnderScc establecido, el archivo del proyecto se debería extraer del repositorio llamando a QueryEditFiles (QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits,...).
Si la llamada QueryEditFiles del archivo del proyecto hace que el archivo se extraiga del repositorio y se recupere la última versión, el proyecto se descarga y se vuelve a cargar. El método UpgradeProject se llama de nuevo una vez que se crea otra instancia del proyecto. En esta segunda llamada, el archivo del proyecto puede escribirse en el disco; se recomienda que el proyecto guarde una copia del archivo del proyecto en el formato anterior con una extensión .OLD, realice los cambios de actualización necesarios y guarde el archivo del proyecto en el nuevo formato. Nuevamente, si se produce un error en cualquier parte del proceso de actualización, el método debe indicarlo mediante la devolución de VS_E_PROJECTMIGRATIONFAILED. Esto hace que el proyecto se descargue en el Explorador de soluciones.
Es importante comprender el proceso completo que tiene lugar en el entorno por si la llamada al método QueryEditFiles (que especifica un valor de ReportOnly) devuelve las marcas QER_EditNotOK y QER_ReadOnlyUnderScc.
El usuario intenta abrir el archivo del proyecto.
El entorno llama a su implementación CanCreateProject.
Si CanCreateProject devuelve
true
, entonces el entorno llama a su implementación CanCreateProject.El entorno llama a su implementación Load para que abra el archivo e inicialice el objeto del proyecto, por ejemplo, Proyecto1.
El entorno llama a su implementación
IVsProjectUpgrade::UpgradeProject
para determinar si debe actualizarse el archivo del proyecto.Debe llamar a QueryEditFiles y pasar un valor de QEF_ReportOnly para el parámetro
rgfQueryEdit
.El entorno devuelve QER_EditNotOK para
VSQueryEditResult
y el bit QER_ReadOnlyUnderScc es establece enVSQueryEditResultFlags
.Su implementación IVsProjectUpgrade llama a
IVsQueryEditQuerySave::QueryEditFiles
(QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits).
Esta llamada puede hacer que se extraiga del repositorio una nueva copia del archivo del proyecto y que se recupere la versión más reciente, así como que se deba volver a cargar el archivo del proyecto. En este punto, ocurren dos cosas:
Si administra su propia recarga del proyecto, el entorno llama a su implementación ReloadItem (VSITEMID_ROOT). Cuando reciba esta llamada, vuelva a cargar la primera instancia del proyecto (Proyecto1) y continúe con la actualización del archivo del proyecto. El entorno sabe que administra su recarga del proyecto si devuelve
true
para GetProperty (VSHPROPID_HandlesOwnReload).Si no administra su recarga del proyecto, devuelve
false
para GetProperty (VSHPROPID_HandlesOwnReload). En este caso, antes de que se devuelva QueryEditFiles(QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits), el entorno crea otra nueva instancia del proyecto, por ejemplo, “Project2”, tal y como se indica a continuación:El entorno llama a Close en el primer objeto del proyecto, Proyecto1, y coloca este objeto en el estado inactivo.
El entorno llama a su implementación
IVsProjectFactory::CreateProject
para crear una segunda instancia de su proyecto, Proyecto2.El entorno llama a su implementación
IPersistFileFormat::Load
para que abra el archivo e inicialice el segundo objeto del proyecto, Proyecto2.El entorno llama a
IVsProjectUpgrade::UpgradeProject
por segunda vez para determinar si se debe actualizar el objeto del proyecto. Sin embargo, esta llamada se realiza en una segunda instancia nueva del proyecto, Proyecto2. Este es el proyecto que se abre en la solución.Nota:
En caso de que su primer proyecto, Proyecto1, se coloque en el estado inactivo, debe devolver S_OK desde la primera llamada a su implementación UpgradeProject.
Debe llamar a QueryEditFiles y pasar un valor de QEF_ReportOnly para el parámetro
rgfQueryEdit
.El entorno devuelve QER_EditOK y la actualización puede continuar porque se puede escribir en el archivo del proyecto.
Si no puede actualizar, devuelva VS_E_PROJECTMIGRATIONFAILED desde IVsProjectUpgrade::UpgradeProject
. Si no es necesario realizar ninguna actualización o si opta por no realizar ninguna actualización, trate la llamada IVsProjectUpgrade::UpgradeProject
como una operación inefectiva. Si devuelve VS_E_PROJECTMIGRATIONFAILED, se agrega un nodo de marcador de posición a la solución del proyecto.
Actualización de elementos de proyecto
Si agrega o administra elementos dentro de los sistemas de proyecto que no implementa, es posible que tenga que participar en el proceso de actualización del proyecto. Crystal Reports es un ejemplo de un elemento que se puede agregar al sistema de proyecto.
Normalmente, los implementadores de elementos de proyecto buscan aprovechar un proyecto ya creado por instancias y actualizados porque necesitan saber cuáles son las referencias del proyecto y qué otras propiedades del proyecto hay para tomar una decisión de actualización.
Para obtener la notificación de actualización del proyecto
Establezca la marca SolutionOrProjectUpgrading (definida en vsshell80.idl) en la implementación del elemento de proyecto. Esto hará que el elemento de proyecto VSPackage se cargue automáticamente cuando el shell de Visual Studio determine que un sistema de proyecto está en proceso de actualización.
Informe a la interfaz IVsSolutionEventsProjectUpgrade a través del método AdviseSolutionEvents.
La interfaz IVsSolutionEventsProjectUpgrade se activa después de que la implementación del sistema del proyecto haya completado sus operaciones de actualización y se cree el nuevo proyecto actualizado. En función del escenario, la interfaz IVsSolutionEventsProjectUpgrade se activará después del método OnAfterOpenSolution, OnAfterOpenProject o OnAfterLoadProject.
Para actualizar los archivos de elementos de proyecto
Debe administrar cuidadosamente el proceso de copia de seguridad de archivos en la implementación del elemento de proyecto. Esto se aplica en particular a las copias de seguridad en paralelo, donde el parámetro
fUpgradeFlag
del método UpgradeProject se establece en PUVFF_SXSBACKUP, donde los archivos de los que se ha realizado una copia de seguridad se colocan junto a los archivos secundarios designados como ".old". Los archivos de copia de seguridad que sean anteriores a la hora del sistema en que se actualizó el proyecto se pueden designar como obsoletos. Es más, se podrían sobrescribir a menos que realice pasos específicos para evitarlo.En el momento en que el elemento del proyecto recibe una notificación de la actualización del proyecto, todavía se muestra el asistente para conversión de Visual Studio. Por lo tanto, debe utilizar los métodos de la interfaz IVsUpgradeLogger para proporcionar mensajes de actualización a la interfaz de usuario del asistente.