Mise à niveau des projets
Les modifications apportées au modèle de projet d’une version de Visual Studio à la suivante peuvent nécessiter la mise à niveau de projets et de solutions afin qu’elles puissent s’exécuter sur la version la plus récente. Le Kit de développement logiciel (SDK) Visual Studio fournit des interfaces qui peuvent être utilisées pour implémenter la prise en charge de la mise à niveau dans vos propres projets.
Stratégies de mise à niveau
Pour prendre en charge une mise à niveau, l’implémentation de votre système de projet doit définir et implémenter une stratégie de mise à niveau. Pour déterminer votre stratégie, vous pouvez choisir de prendre en charge la sauvegarde côte à côte (SxS), la sauvegarde de copie ou les deux.
La sauvegarde SxS signifie qu’un projet copie uniquement sur place les fichiers qui ont besoin d’être mis à niveau, en ajoutant un suffixe de nom de fichier approprié, par exemple « .old ».
La sauvegarde de copie signifie qu’un projet copie tous les éléments de projet vers un emplacement de sauvegarde fourni par l’utilisateur. Les fichiers concernés à l’emplacement du projet d’origine sont ensuite mis à niveau.
Fonctionnement de la mise à niveau
Lorsqu’une solution créée dans une version antérieure de Visual Studio est ouverte dans une version plus récente, l’IDE vérifie le fichier de solution pour déterminer s’il doit être mis à niveau. Si la mise à niveau est nécessaire, l’Assistant de mise à niveau est automatiquement lancé pour guider l’utilisateur dans le processus de mise à niveau.
Lorsqu’une solution a besoin d’une mise à niveau, elle interroge chaque fabrique de projets pour connaître sa stratégie de mise à niveau. La stratégie détermine si la fabrique de projets prend en charge la sauvegarde de copie ou la sauvegarde SxS. Les informations sont envoyées à l’Assistant de mise à niveau, qui collecte les informations requises pour la sauvegarde et présente les options applicables à l’utilisateur.
Solutions à projets multiples
Si une solution contient plusieurs projets et que les stratégies de mise à niveau diffèrent, par exemple avec un projet C++ prenant uniquement en charge la sauvegarde SxS et un projet Web prenant uniquement en charge la sauvegarde de copie, les fabriques de projets doivent négocier la stratégie de mise à niveau.
La solution interroge chaque fabrique de projet pour connaître sa IVsProjectUpgradeViaFactory. Il appelle ensuite UpgradeProject_CheckOnly pour voir si les fichiers projet globaux doivent être mis à niveau et pour déterminer les stratégies de mise à niveau prises en charge. L’Assistant de mise à niveau est ensuite appelé.
Une fois que l’utilisateur a terminé l’assistant, UpgradeProject est appelé sur chaque fabrique de projet pour effectuer la mise à niveau réelle. Pour faciliter la sauvegarde, les méthodes IVsProjectUpgradeViaFactory fournissent au service SVsUpgradeLogger la journalisation des détails du processus de mise à niveau. Ce service ne peut pas être mis en cache.
Après avoir mis à jour tous les fichiers globaux concernés, chaque fabrique de projet peut choisir d’instancier un projet. L’implémentation du projet doit prendre en charge IVsProjectUpgrade. La méthode UpgradeProject est ensuite appelée pour mettre à niveau tous les éléments de projet concernés.
Remarque
La méthode UpgradeProject ne fournit pas le service SVsUpgradeLogger. Ce service peut être obtenu en appelant le QueryService.
Meilleures pratiques
Utilisez le service SVsQueryEditQuerySave pour vérifier si vous pouvez modifier un fichier avant de le modifier et si vous pouvez l’enregistrer avant de l’enregistrer. Cela aidera vos implémentations de sauvegarde et de mise à niveau à gérer les fichiers projet sous le contrôle de code source, les fichiers avec des autorisations insuffisantes, etc.
Utilisez le service SVsUpgradeLogger pendant toutes les phases de sauvegarde et de mise à niveau pour fournir des informations sur la réussite ou l’échec du processus de mise à niveau.
Pour plus d’informations sur la sauvegarde et la mise à niveau de projets, consultez les commentaires pour IVsProjectUpgrade dans vsshell2.idl.
Mise à niveau de projets personnalisés
Si vous modifiez les informations persistantes dans le fichier projet entre des versions Visual Studio différentes de votre produit, vous devez prendre en charge la mise à niveau de votre fichier projet vers la version la plus récente. Pour prendre en charge la mise à niveau qui vous permet de participer à l’Assistant de conversion de Visual Studio, implémentez l’interface IVsProjectUpgradeViaFactory. Cette interface fournit le seul mécanisme disponible pour mettre à niveau une copie. La mise à niveau du projet est une étape du processus d’ouverture de la solution. L’interface IVsProjectUpgradeViaFactory est implémentée par la fabrique de projet. Sinon, elle doit pouvoir être obtenue à partir de la fabrique de projet.
L’ancien mécanisme qui utilise l’interface IVsProjectUpgrade est toujours pris en charge, mais il est conçu pour mettre à niveau le système de projet pendant le processus d’ouverture du projet. L’interface IVsProjectUpgrade est donc appelée par l’environnement Visual Studio même si l’interface IVsProjectUpgradeViaFactory est appelée ou implémentée. Cette approche vous permet d’utiliser IVsProjectUpgradeViaFactory pour implémenter uniquement la mise à niveau du projet et de la copie, et de déléguer le reste du travail à effectuer sur place (éventuellement au nouvel emplacement) par l’interface IVsProjectUpgrade.
Pour obtenir un exemple d’implémentation de IVsProjectUpgrade, consultez les exemples de VSSDK.
Scénarios possibles lors d’une mise à niveau de projet :
Si le fichier présente un format récent non pris en charge par le projet, il doit retourner une erreur indiquant ce problème. Cela suppose que la version antérieure de votre produit inclue le code de vérification de la version.
Si l’indicateur PUVFF_SXSBACKUP est spécifié dans la méthode UpgradeProject, la mise à niveau est implémentée en tant que mise à niveau sur place avant l’ouverture du projet.
Si l’indicateur PUVFF_COPYBACKUP est spécifié dans la méthode UpgradeProject, la mise à niveau est implémentée en tant que mise à niveau de la copie.
Si l’indicateur UPF_SILENTMIGRATE est spécifié dans l’appel à UpgradeProject, l’utilisateur est invité par l’environnement à mettre à niveau le fichier projet en tant que mise à niveau sur place, une fois le projet ouvert. Par exemple, l’environnement invite l’utilisateur à effectuer la mise à niveau quand celui-ci ouvre une version antérieure de la solution.
Si l’indicateur UPF_SILENTMIGRATE n’est pas spécifié dans l’appel à UpgradeProject, vous devez inviter l’utilisateur à mettre à niveau le fichier projet.
Voici un exemple de message d’invite de mise à niveau :
« Le projet '%1' a été créé avec une version antérieure de Visual Studio. Si vous l’ouvrez avec cette version de Visual Studio, vous ne pourrez peut-être plus l’ouvrir avec les versions antérieures de Visual Studio. Voulez-vous continuer et ouvrir ce projet ? »
Pour implémenter IVsProjectUpgradeViaFactory
Implémentez la méthode de l’interface IVsProjectUpgradeViaFactory, à savoir la méthode UpgradeProject dans votre implémentation de la fabrique de projet, ou définissez les implémentations pour qu’elles puissent être appelées à partir de votre implémentation de la fabrique de projet.
Si vous souhaitez effectuer une mise à niveau sur place à l’ouverture de la solution, spécifiez l’indicateur PUVFF_SXSBACKUP en tant que paramètre
VSPUVF_FLAGS
dans votre implémentation d’UpgradeProject.Si vous souhaitez effectuer une mise à niveau sur place à l’ouverture de la solution, spécifiez l’indicateur PUVFF_COPYBACKUP en tant que paramètre
VSPUVF_FLAGS
dans votre implémentation d’UpgradeProject.Pour les étapes 2 et 3, vous pouvez implémenter les étapes de mise à niveau du fichier, avec IVsQueryEditQuerySave2, comme décrit dans la section « Implémentation d’
IVsProjectUpgade
» ci-dessous, ou déléguer la mise à niveau du fichier à IVsProjectUpgrade.Utilisez les méthodes d’IVsUpgradeLogger pour publier les messages de mise à niveau à l’intention de l’utilisateur à l’aide de l’Assistant Migration de Visual Studio.
L’interface IVsFileUpgrade permet d’implémenter tout type de mise à niveau de fichier devant être effectuée dans le cadre de la mise à niveau du projet. Cette interface n’est pas appelée à partir de l’interface IVsProjectUpgradeViaFactory. Elle fournit un mécanisme de mise à niveau de fichiers qui font partie du système de projet, mais dont celui-ci n’a pas directement connaissance. Par exemple, cette situation peut se produire si les fichiers et les propriétés liés au compilateur ne sont pas gérés par la même équipe de développement que celle qui gère le reste du système de projet.
Implémentation d’IVsProjectUpgrade
Si votre système de projet implémente IVsProjectUpgrade uniquement, il ne peut pas participer à l’Assistant de conversion de Visual Studio. Toutefois, même si vous implémentez l’interface IVsProjectUpgradeViaFactory, vous pouvez déléguer la mise à niveau du fichier à l’implémentation d’IVsProjectUpgrade.
Pour implémenter IVsProjectUpgrade
Quand un utilisateur tente d’ouvrir un projet, la méthode UpgradeProject est appelée par l’environnement après l’ouverture du projet et avant toute autre action de l’utilisateur sur le projet. Si l’utilisateur a déjà été invité à mettre à niveau la solution, l’indicateur UPF_SILENTMIGRATE est passé au paramètre
grfUpgradeFlags
. Si l’utilisateur ouvre directement un projet, par exemple à l’aide de la commande Ajouter un projet existant, l’indicateur UPF_SILENTMIGRATE n’est pas passé et le projet doit inviter l’utilisateur à effectuer la mise à niveau.En réponse à l’appel à UpgradeProject, le projet doit évaluer si le fichier projet a été mis à niveau. Si le projet n’a pas besoin de mettre à niveau le type de projet vers une nouvelle version, il peut simplement retourner l’indicateur S_OK.
Si le projet doit mettre à niveau le type de projet vers une nouvelle version, il doit déterminer si le fichier projet peut être modifié en appelant la méthode QueryEditFiles et en passant une valeur de tagVSQueryEditFlags pour le paramètre
rgfQueryEdit
. Ensuite, le projet doit effectuer les opérations suivantes :Si la valeur de retour de
VSQueryEditResult
dans le paramètrepfEditCanceled
est QER_EditOK, la mise à niveau peut continuer, car le fichier projet peut être modifié.Si la valeur de retour de
VSQueryEditResult
dans le paramètrepfEditCanceled
est QER_EditNotOK et que la valeurVSQueryEditResult
a le bit QER_ReadOnlyNotUnderScc défini, UpgradeProject doit retourner une erreur, car il s’agit d’un problème d’autorisation devant être résolu par l’utilisateur. Le projet doit alors effectuer les opérations suivantes :Signalez l’erreur à l’utilisateur en appelant ReportErrorInfo et en renvoyant le code d’erreur VS_E_PROJECTMIGRATIONFAILED à IVsProjectUpgrade.
Si la valeur de
VSQueryEditResult
est QER_EditNotOK et que la valeur deVSQueryEditResultFlags
a le bit QER_ReadOnlyUnderScc défini, le fichier projet doit être extrait en appelant QueryEditFiles (QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits, ...).
Si l’appel à QueryEditFiles sur le fichier projet entraîne l’extraction du fichier et la récupération de la version la plus récente, le projet est déchargé et rechargé. La méthode UpgradeProject est rappelée après la création d’une autre instance du projet. À ce deuxième appel, le fichier projet peut être écrit sur le disque. Il est recommandé que le projet enregistre une copie du fichier projet dans le format antérieur avec l’extension de fichier .OLD, qu’il apporte les modifications nécessaires pour la mise à niveau, puis qu’il enregistre le fichier projet dans le nouveau format. Là encore, si une étape de la mise à niveau échoue, la méthode doit indiquer une erreur en retournant VS_E_PROJECTMIGRATIONFAILED. Le projet est alors déchargé dans l’Explorateur de solutions.
Il est important de bien comprendre le déroulement du processus exécuté dans l’environnement quand l’appel à la méthode QueryEditFiles (en spécifiant une valeur pour ReportOnly) retourne les indicateurs QER_EditNotOK et QER_ReadOnlyUnderScc.
L’utilisateur tente d’ouvrir le fichier projet.
L’environnement appelle votre implémentation de CanCreateProject.
Si CanCreateProject retourne
true
, l’environnement appelle votre implémentation de CanCreateProject.L’environnement appelle votre implémentation de Load pour ouvrir le fichier et initialiser l’objet projet, par exemple, Projet1.
L’environnement appelle votre implémentation d’
IVsProjectUpgrade::UpgradeProject
pour déterminer si le fichier projet doit être mis à niveau.Vous appelez QueryEditFiles et passez une valeur de QEF_ReportOnly pour le paramètre
rgfQueryEdit
.L’environnement retourne QER_EditNotOK pour
VSQueryEditResult
et le bit QER_ReadOnlyUnderScc est défini dansVSQueryEditResultFlags
.Votre implémentation d’IVsProjectUpgrade appelle
IVsQueryEditQuerySave::QueryEditFiles
(QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits).
Cet appel peut entraîner l’extraction d’une nouvelle copie de votre fichier projet et la récupération de la version la plus récente, ainsi que la nécessité de recharger votre fichier projet. À ce stade, il y a deux cas de figure possibles :
Si vous gérez votre propre rechargement du projet, l’environnement appelle votre implémentation de ReloadItem (VSITEMID_ROOT). Quand vous recevez cet appel, rechargez la première instance de votre projet (Projet1) et continuez la mise à niveau de votre fichier projet. L’environnement sait que vous gérez votre propre rechargement du projet si vous retournez
true
pour GetProperty (VSHPROPID_HandlesOwnReload).Si vous ne gérez pas votre propre rechargement du projet, retournez
false
pour GetProperty (VSHPROPID_HandlesOwnReload). Dans ce cas, avant le retour de QueryEditFiles(QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits), l’environnement crée une autre instance de votre projet, par exemple Project2, comme suit :L’environnement appelle Close sur le premier objet projet (Projet1), ce qui fait passer cet objet à l’état inactif.
L’environnement appelle votre implémentation d’
IVsProjectFactory::CreateProject
pour créer une deuxième instance de votre projet (Projet2).L’environnement appelle votre implémentation d’
IPersistFileFormat::Load
pour ouvrir le fichier et initialiser le deuxième objet projet (Projet2).L’environnement appelle
IVsProjectUpgrade::UpgradeProject
une deuxième fois pour déterminer si l’objet projet doit être mis à niveau. Toutefois, cet appel est effectué sur la nouvelle instance (la deuxième) du projet, Projet2. Il s’agit du projet qui est ouvert dans la solution.Remarque
Dans l’instance de votre premier projet, Projet1, qui est à l’état inactif, vous devez retourner S_OK à partir du premier appel à votre implémentation d’UpgradeProject.
Vous appelez QueryEditFiles et passez une valeur de QEF_ReportOnly pour le paramètre
rgfQueryEdit
.L’environnement retourne QER_EditOK. La mise à niveau peut continuer, car le fichier projet peut être modifié.
Si la mise à niveau échoue, retournez VS_E_PROJECTMIGRATIONFAILED à partir d’IVsProjectUpgrade::UpgradeProject
. Si aucune mise à niveau n’est nécessaire ou si vous choisissez de ne pas faire la mise à niveau, gérez l’appel IVsProjectUpgrade::UpgradeProject
comme une absence d’opération. Si vous retournez VS_E_PROJECTMIGRATIONFAILED, un nœud d’espace réservé est ajouté à la solution pour votre projet.
Mise à niveau d’éléments de projet
Si vous ajoutez ou gérez des éléments à l’intérieur des systèmes de projet que vous n’implémentez pas, vous devrez peut-être participer au processus de mise à niveau du projet. Crystal Reports est un exemple d’élément qui peut être ajouté au système de projet.
En règle générale, les implémenteurs d’éléments de projet souhaitent tirer parti d’un projet déjà totalement instancié et mis à niveau, car ils doivent savoir quelles sont les références du projet et quelles autres propriétés du projet sont disponibles pour prendre une décision de mise à niveau.
Pour obtenir la notification de mise à niveau du projet
Définissez l’indicateur SolutionOrProjectUpgrading (défini dans vsshell80.idl) dans l’implémentation de votre élément de projet. Cela entraîne le chargement automatique de l’élément de projet VSPackage lorsque le shell Visual Studio détermine qu’un système de projet est en cours de mise à niveau.
Avertir l’interface IVsSolutionEventsProjectUpgrade via la méthode AdviseSolutionEvents.
L’interface IVsSolutionEventsProjectUpgrade est déclenchée une fois que l’implémentation du système de projet a terminé ses opérations de mise à niveau et que le nouveau projet mis à niveau est créé. En fonction du scénario, l’interface IVsSolutionEventsProjectUpgrade est déclenchée après la méthode OnAfterOpenSolution, OnAfterOpenProject ou OnAfterLoadProject.
Pour mettre à niveau les fichiers d’élément de projet
Vous devez gérer soigneusement le processus de sauvegarde de fichiers dans l’implémentation de l’élément de projet. Cela s’applique en particulier à la sauvegarde côte à côte, où le paramètre
fUpgradeFlag
de la méthode UpgradeProject est défini sur PUVFF_SXSBACKUP, où les fichiers qui ont été sauvegardés sont placés avec les fichiers désignés comme « .old ». Les fichiers sauvegardés antérieurs à l’heure système à laquelle le projet a été mis à niveau peuvent être désignés comme obsolètes. Ils peuvent également être remplacés, sauf si vous prenez des mesures spécifiques pour éviter cela.Au moment où votre élément de projet reçoit une notification de mise à niveau du projet, l’Assistant de conversion Visual Studio est encore affiché. Par conséquent, vous devez utiliser les méthodes de l’interface IVsUpgradeLogger pour fournir des messages de mise à niveau vers l’IU de l’assistant.