web-dev-qa-db-fra.com

La tâche de déploiement Web de publication VS2013 a échoué Le fichier est en cours d'utilisation

J'utilise VS2013 Premium pour publier un site sur Windows Server 2012. Tous les fichiers sont corrects, à l'exception de ceux-ci: SqlServerTypes\x64\msvcr100.dll

SqlServerTypes\x64\SqlServerSpatial110.dll

SqlServerTypes\x86\msvcr100.dll

SqlServerTypes\x86\SqlServerSpatial110.dll

Je reçois ce type d'erreur pour chacun des fichiers ci-dessus que j'ai essayé de publier: La tâche de déploiement Web a échoué. (Le fichier 'msvcr100.dll' est en cours d'utilisation. Pour en savoir plus, visitez le site: http://go.Microsoft.com/fwlink/?LinkId=221672#ERROR_FILE_IN_USE .)

Il est intéressant de noter que ces fichiers ont été publiés la première fois (lorsqu'ils n'étaient pas sur le serveur), ils ne sont plus écrasés. J'ai essayé avec 2 serveurs Web différents ... J'ai suivi le guide ici: http://blogs.msdn.com/b/webdev/archive/2013/10/30/web-publishing-updates- pour-app-offline-and-usechecksum.aspx

... Mais il a seulement réussi à mettre le site hors ligne (VS place app_offline.htm), mais la publication échoue toujours avec la même erreur . Tous les autres fichiers sont publiés à la perfection.

Des idées?

28
user3546827

Vous pouvez mettre votre application hors ligne pendant la publication, ce qui devrait permettre de libérer le verrou sur le fichier et de vous permettre de le mettre à jour.

J'ai blogué à ce sujet il y a quelque temps. La prise en charge décrite a été fournie avec Azure SDK et Visual Studio Update. Je ne me souviens pas des versions exactes, mais je peux le savoir si nécessaire. Toute mise à jour datant de/après cet article de blog devrait convenir.

Conditions préalables:

  • Mise à jour VS 2012 + VS/Mise à jour VS 2013 + VS/VS2015
  • MSDeploy v3

Remarque: si vous publiez à partir d'un serveur CI, le serveur CI aura également besoin des mises à jour ci-dessus

Modifier le profil de publication

Lorsque vous créez un profil Web Publish dans VS, les paramètres de la boîte de dialogue sont stockés dans Properties\PublishProfiles\ sous forme de fichiers se terminant par .pubxml. Remarque: il existe également un fichier .pubxml.user, ce fichier ne doit pas être modifié

Pour déconnecter votre application du fichier .pubxml, ajoutez la propriété suivante.

<EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>

Remarques

ASP.NET requis

La manière dont cela a été implémenté du côté MSDeploy est qu'un fichier app_offline.htm est déposé à la racine du site Web/de l'application. À partir de là, le runtime asp.net le détectera et mettra votre application hors ligne. Pour cette raison, si votre site/application n'a pas activé asp.net, cette fonction ne fonctionnera pas.

Cas où cela peut ne pas fonctionner

L'implémentation de cette fonctionnalité fait en sorte que l'application ne soit pas strictement déconnectée avant le début de la publication. Tout d'abord, le fichier app_offline.htm est supprimé, puis MSDeploy commence à publier les fichiers. Il n'attend pas qu'ASP.NET détecte le fichier et le déconnecte. Pour cette raison, vous pouvez rencontrer des cas où vous rencontrez toujours le verrou de fichier. Par défaut, VS active les tentatives de tentative. Ainsi, l'application passe hors ligne pendant l'une des tentatives et tout va bien. Dans certains cas, ASP.NET peut prendre plus de temps pour répondre. C'est un peu plus délicat.

Si vous ajoutez <EnableMSDeployAppOffline>true</EnableMSDeployAppOffline> et que votre application n'est pas mise hors ligne assez tôt, je vous suggère de la mettre hors ligne avant le début de la publication. Il existe plusieurs façons de procéder à distance, mais cela dépend de votre configuration. Si vous ne disposez que d’un accès MSDeploy, vous pouvez essayer la séquence suivante:

  1. Utilisez msdeploy.exe pour déconnecter votre site en laissant tomber app_offline.htm.
  2. Utilisez msdeploy.exe pour publier votre application (_ assurez-vous que la synchronisation ne supprime pas le fichier app_offline.htm_)
  3. Attendre un peu de temps
  4. Publier le site
  5. Utilisez msdeploy.exe pour mettre l'application en ligne en supprimant app_offline.htm.

J'ai blogué comment vous pouvez faire cela à http://sedodream.com/2012/01/08/howtotakeyourwebappofflineduringpublishing.aspx . La seule chose qui manque à cet article de blog est le délai d'attente pour que le site soit réellement déconnecté. Vous pouvez également créer un script qui appelle simplement msdeploy.exe directement au lieu de l'intégrer au processus de construction/publication du projet.

23

J'ai trouvé la raison pour laquelle la solution à http://blogs.msdn.com/b/webdev/archive/2013/10/30/web-publishing-updates-for-app-offline-and- usechecksum.aspx n'a pas fonctionné pour l'affiche originale et j'ai une solution de contournement.

Le problème avec l'approche EnableMSDeployAppOffline est qu'elle ne fait que recycler le domaine d'application hébergeant l'application. Il ne recycle pas le processus de traitement de pool d'applications (w3wp.exe) dans lequel le domaine d'application réside. 

Abattre et recréer le domaine d'application n'affectera pas les dll Sql Server Spatial en question. Ces dll sont du code non managé chargé manuellement via des appels interop LoadLibray. Par conséquent, les dll vivent en dehors du domaine d'application.

Afin de libérer les verrous de fichiers, que le processus de pool d'applications leur applique, vous devez soit recycler le pool d'applications, soit décharger manuellement les dll de la mémoire.

Le package de nuget Microsoft.SqlServer.Types fournit une classe utilisée pour charger les dll spatiales appelées SqlServerTypes.Utilities. Vous pouvez modifier la méthode LoadNativeAssemblies pour décharger les dll non gérées lorsque le domaine d'application est déchargé. Avec cette modification, lorsque msdeploy copie app_offline.htm, le domaine d'application sera déchargé, puis déchargé également les dll gérées.

private static IntPtr _msvcrPtr = IntPtr.Zero;
private static IntPtr _spatialPtr = IntPtr.Zero;

public static void LoadNativeAssemblies(string rootApplicationPath)
{
    if (_msvcrPtr != IntPtr.Zero || _spatialPtr != IntPtr.Zero)
        throw new Exception("LoadNativeAssemblies already called.");

    var nativeBinaryPath = IntPtr.Size > 4
        ? Path.Combine(rootApplicationPath, @"SqlServerTypes\x64\")
        : Path.Combine(rootApplicationPath, @"SqlServerTypes\x86\");

    _msvcrPtr = LoadNativeAssembly(nativeBinaryPath, "msvcr100.dll");
    _spatialPtr = LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial110.dll");

    AppDomain.CurrentDomain.DomainUnload += (sender, e) =>
    {
        if (_msvcrPtr != IntPtr.Zero)
        {
            FreeLibrary(_msvcrPtr);
            _msvcrPtr = IntPtr.Zero;
        }

        if (_spatialPtr != IntPtr.Zero)
        {
            FreeLibrary(_spatialPtr);
            _spatialPtr = IntPtr.Zero;
         }
    };
}

Il y a une mise en garde avec cette approche. Cela suppose que votre application est la seule qui s'exécute dans le processus de travail et qui utilise les dll Spatial. Comme les pools d'applications peuvent héberger plusieurs applications, les verrous de fichiers ne seront pas libérés si une autre application les a également chargés. Cela empêchera votre déploiement de fonctionner avec la même erreur de verrouillage de fichier.

4
Paul

Je pense que la chose la plus facile à faire est de rendre ces DLL aussi vraies que CopyLocal. Je suppose que ces dll sont extraites du dossier de fichiers de programme. Essayez de les marquer en tant que copylocal true et effectuez un déploiement. Essayez d'arrêter tout processus local IIS exécuté sur votre ordinateur local.

1
qamar

Il existe des problèmes connus avec IIS et les verrous de fichiers (pourquoi ils ne sont pas encore résolus, je ne sais pas).

La question que je veux poser est cependant si vous avez même besoin de redéployer ces fichiers?

Je reconnais les noms de fichiers et les rappelle comme étant des fichiers système qui devraient déjà être présents sur le serveur ou n’avoir tout simplement pas besoin d’être redéployés.

Je ne suis pas très expérimenté en ce qui concerne IIS, mais j’ai déjà rencontré ce problème auparavant et plusieurs de mes collègues plus expérimentés m’ont dit que c’était comme je l’ai dit un problème connu de IIS et je crois la réponse. à votre question est:

  1. Évitez de déployer des fichiers inutiles.
  2. réessayer
  3. Réinitialiser le site
  4. réessayer
  5. iisreset
1
DOOMDUDEMX

Attention, aucun de ces nouveaux services de sauvegarde sur le cloud en cours d'exécution ne prend des verrous de fichiers. De plus, rien ne s'ouvre dans Explorer ou dans un outil d'inspection DLL.

Je pense que c'est un peu ridicule que MS ne fasse pas de meilleures provisions pour ce problème. Je constate que 9 fois sur 10, mon déploiement fonctionne parfaitement, mais à mesure que notre trafic augmente, il peut atteindre 1 fois sur 10.

Je vais résoudre le problème avec:

  • deux applications MySite.A et MySite.B, où une seule est en cours d'exécution à la fois. 
  • Je déploie toujours ensuite sur le site dormant. 
  • En cas de problème lors du déploiement, le site entier ne sera jamais en panne.
  • En cas de problème majeur après le déploiement, vous pouvez revenir très facilement.

Je ne sais pas trop comment je vais la mettre en œuvre, mais je pense que c'est ce que je dois faire.

0
Simon_Weaver