VS2013 publish Web deployment task failed The file is in use
Asked Answered
K

5

33

I am using VS2013 Premium to publish a site to Windows Server 2012. All files publish ok except these: SqlServerTypes\x64\msvcr100.dll

SqlServerTypes\x64\SqlServerSpatial110.dll

SqlServerTypes\x86\msvcr100.dll

SqlServerTypes\x86\SqlServerSpatial110.dll

I get this kind of errors for each of the above files I tried to publish: Web deployment task failed. (The file 'msvcr100.dll' is in use. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_FILE_IN_USE.)

Interrestingly, these files were published the first time (when they were not on the server), then they are no longer overwritten. Tried with 2 different web servers. I have followed the guide here: http://blogs.msdn.com/b/webdev/archive/2013/10/30/web-publishing-updates-for-app-offline-and-usechecksum.aspx

...But it only managed to put the site offline (VS is placing the app_offline.htm) but publish still fails with the same error. All other files publish perfectly.

Any ideas?

Kings answered 5/12, 2014 at 22:50 Comment(14)
Did you try to run VS as administrator ?! I got similar error in a project due to permissions.Raeraeann
Make sure that the site isn't running locally on your machine.Paviour
I am trying to publish to a different machine. VS was started as administrator and the site is not running locally (VS tried to start it but I killed it). The message in output console is:Kings
I am trying to publish to a different machine. VS was started as administrator and the site is not running locally (VS tried to start it but I killed it). I have verified the file both locally and on the server with IOUnlocker just to see if there is any lock in the file and there isn't. The message in output console is: Updating file (Default Web Site\bin\SqlServerTypes\x64\msvcr100.dll). 3>C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.targets(4270,5): Error ERROR_FILE_IN_USE: Web deployment task failed. (The file 'msvcr100.dll' is in use.Kings
I too am having this issue. Can't seem to figure it out. We've been stopping IIS before every deployment. It's the only way it seems to work.Daytoday
I think IIS express is keeping them open, even after your exit your web application. This is a sign that you should check your code and make sure you are properly disposing of unused objects correctly (e.g. surrounding IDisposable objects in using blocks)Maynardmayne
Have you tried using "handle" from sysinternals. It can often tell you what process has a handle to a given file. You might even be able to run the program, get the output, parse it and release the locks - but I am getting WAY ahead of myself :)Vashti
I think this is not an issue with the machine you're publishing from but rather the target machine. Is the configured WebDeploy user an administrator? I might start there, then for NonAdminUser deployments I would follow the following section IIS MANAGER TO CONFIGURE WEB DEPLOY FOR A NON-ADMINISTRATORWrap
Find first what is using the file using Sysinternals Process Explorer on server as suggested by Derek. Then also consider if it is a really big problem to not to have theese files allways rewritten with the same DLL version - change them to copy if newer.Shaunshauna
In my experience; it's your local machine that's the issue. IIS Express is usually the culprit here but sometimes restarting/ending that doesn't always sort it. I've sometimes had to completely shut down all instances of Visual Studio and/or delete the contents of the Bin folder - I find this sort of issue likes to happen when you have multiple projects open where code is in some way shared between the two.Mcglothlin
I always use Unlocker emptyloop.com/unlocker for things like this to work out first what process is using/locking the file. Be careful to unselect the adware during the installation though!Corona
@Kings Have you tried FTPing in and deleting them manually?Leguminous
Yes deleting files and removing references to the libraries was the first step. The problem fix I presented below. I did not really identify the cause, but it may help someone fix their problems in the future.Kings
More modern answer here: #37919150Hydrostatics
T
27

You can take you app offline during publishing which hopefully should free up the lock on the file and allow you to update it.

I blogged about this a while back. The support outlined was shipped inside of the Azure SDK and Visual Studio Update. I don't remember the exact releases but I can find out if needed. Any update dating around/after that blog post should be fine.

Prerequisites:

  • VS 2012 + VS update / VS 2013 + VS Update / VS2015
  • MSDeploy v3

Note: if you are publishing from a CI server the CI server will need the updates above as well

Edit the publish profile

In VS when create a Web Publish profile the settings from the dialog are stored in Properties\PublishProfiles\ as files that end with .pubxml. Note: there is also a .pubxml.user file, that file should not be modified

To take your app offline in the .pubxml file add the following property.

<EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>

Notes

ASP.NET Required

The way that this has been implemented on the MSDeploy side is that an app_offline.htm file is dropped in the root of the website/app. From there the asp.net runtime will detect that and take your app offline. Because of this if your website/app doesn't have asp.net enabled this function will not work.

Cases where it may not work

The implementation of this makes it such that the app may not strictly be offline before publish starts. First the app_offline.htm file is dropped, then MSDeploy will start publishing the files. It doesn't wait for ASP.NET to detect the file and actually take it offline. Because of this you may run into cases where you still run into the file lock. By default VS enables retrys so usually the app will go offline during one of the retrys and all is good. In some cases it may take longer for ASP.NET to respond. That is a bit more tricky.

In the case that you add <EnableMSDeployAppOffline>true</EnableMSDeployAppOffline> and your app is not getting taken offline soon enough then I suggest that you take the app offline before the publish begins. There are several ways to do this remotely, but that depends on your setup. If you only have MSDeploy access you can try the following sequence:

  1. Use msdeploy.exe to take your site offline by dropping app_offline.htm
  2. Use msdeploy.exe to publish your app (_make sure the sync doesn't delete the app_offline.htm file_)
  3. Wait some amount of time
  4. Publish the site
  5. Use msdeploy.exe to bring the app online by deleting app_offline.htm

I have blogged how you can do this at http://sedodream.com/2012/01/08/howtotakeyourwebappofflineduringpublishing.aspx. The only thing that is missing from that blog post is the delay to wait for the site to actually be taken offline. You can also create a script that just calls msdeploy.exe directly instead of integrating it into the project build/publish process.

Tippett answered 6/1, 2015 at 3:42 Comment(1)
Actually the fix was in the idea of you answer and most of the comments here. Basically freeing the lock on the files was a necessary first step. Then I decided to remove the package SQL Server Spacial Types (Spatial - by Microsoft) and removed the culprit files. Then I tried with SQL Server Spacial Types (#foo) NuGet package because I needed those functions. Unfortunately while this package had no problems with the publishing, the code with these libraries did not behave correctly. Then I removed this and got back to the Microsoft package. Publishing now works correctly and no more errors.Kings
C
10

I have found the reason why the solution at http://blogs.msdn.com/b/webdev/archive/2013/10/30/web-publishing-updates-for-app-offline-and-usechecksum.aspx did not work for the original poster, and I have a workaround.

The issue with the EnableMSDeployAppOffline approach is that it only recycles the app domain hosting the application. It does not recycle the app pool worker process (w3wp.exe) which the app domain lives in.

Tearing down and recreating the app domain will not affect the Sql Server Spatial dlls in question. Those dlls are unmanaged code which are manually loaded via interop LoadLibray calls. Therefore the dlls live outside the purview of the app domain.

In order to release the files locks, which the app pool process puts on them, you need to either recycle the app pool, or unload the dlls from memory manually.

The Microsoft.SqlServer.Types nuget package ships a class which is used to load the Spatial dlls called SqlServerTypes.Utilities. You can modify the LoadNativeAssemblies method to unload the unmanaged dlls when the app domain is unloaded. With this modification when msdeploy copys the app_offline.htm the app domain will unload and then unload the managed dlls as well.

[DllImport("kernel32.dll", SetLastError = true)]
internal extern static bool FreeLibrary(IntPtr hModule);

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;
         }
    };
}

There is one caveat with this approach. It assumes your application is the only one running in the worker process that is using the Spatial dlls. Since app pools can host multiple applications the file locks will not be released if another application has also loaded them. This will prevent your deploy from working with the same file locked error.

Cryptanalysis answered 18/9, 2015 at 21:38 Comment(1)
Ideal solution for my scenario. It allows us to deploy without requiring the deploy user to have permissions on the IIS server, something other proposed solutions do require.Riddle
R
1

There are known issues with IIS and file-locks (why they aren't solved yet i dont know).

The question i want to ask however is if you even need to re-deploy these files?

I recognize the file-names and recall them to be system-files which should either already be present on the server or simply not need to be re-deployed.

I am not very experienced when it comes to IIS but i have ran into this problem before and several of my more experienced co-workers have told me that this is as i said a known IIS-issue and i believe the answer to your question is:

  1. Avoid deploying unnecessary files.
  2. try again
  3. Reset website
  4. try again
  5. iisreset
Resource answered 6/1, 2015 at 3:21 Comment(0)
P
1

I think what would be the easiest thing to do is to make these dll's as CopyLocal as true. I am assuming these dll's are pulled out from program files folder. Try marking them as copylocal true and do a deployment.Try to stop any IIS local process running in your local machine.

Pointblank answered 6/1, 2015 at 3:25 Comment(0)
E
0

Watch out you don't have one of those new-fangled cloud backup services running that is taking file locks - and also you don't have things open in explorer or a DLL inspection tool.

I think it's kind of ridiculous that MS doesn't make better provisions for this problem. I find that 9 times out of 10 my deployment works just fine, but then as our traffic increases that can become 1 in 10 times.

I am going to solve the problem with :

  • two applications MySite.A and MySite.B, where only one is running at a time.
  • I always then deploy to the dormant site.
  • If there's a problem during the deployment it will never cause the whole site to go down.
  • If there's a major problem after deployment you can revert back very easily.

Not quite sure how I'm implementing it, but I think this is what I need to do.

Eustazio answered 14/4, 2017 at 22:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.