Проблемы с блокировкой файла сборки Visual Studio 2010

У меня есть проект Visual Studio 2008, который я "обновил" до Visual Studio 2010. С момента обновления у меня возникло много проблем с проектом (проект, который был и остается trooper в 2008 году, я мог бы добавить).

Первая проблема заключается в том, что создание основного исполняемого файла блокирует исполняемый файл, что приводит к сбою последующих перестроек. Это описано в связанном с этим вопросе: Visual Studio блокирует выходной файл в сборке, где я взял обходной путь:

if exist "$(TargetPath).locked" del "$(TargetPath).locked"
if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"

Кроме того, обходной путь работает ровно один раз. Заблокированный файл затем блокируется также с помощью файла devenv.exe и должен быть перемещен. Я работал над этим, добавив:.1.,.2.locked и т.д. Единственный раз, когда блокировки удаляются, поэтому файлы могут быть удалены при выключении devenv.exe(требуется несколько секунд после пользовательского интерфейса исчезает, то файлы можно удалить).

Тот факт, что отладчик не должен использоваться, чтобы вызвать эту проблему, указывает на довольно серьезную проблему с системой сборки 2010 года.

Некоторые теории, я думаю, могу сэкономить:

  • Антивирус или другие фоновые задачи: если бы это было проблемой, казалось бы, что 2008 год потерпит неудачу. Однако, будучи самым полным, я удалил avast! системы полностью без везения.

UPDATE: этот проект имеет те же симптомы на машине без антивируса и без утилиты резервного копирования. На машинах в офисе работает XP SP3 32bit, мой локальный компьютер - Windows 7 64 бит. Это, по-видимому, не зависит от ОС.

  • Отладчик блокирует файл: все, что требуется для воспроизведения, это повторение процесса сборки без отладки. ProcessExplorer показывает, что devenv.exe является владельцем блокировок, а не vshost и убивает vshost.exe, в любом случае не удаляет блокировки.

У меня есть вторичная проблема, которая начинает возникать после блокировки файлов: дизайнеры форм перестают загружаться с ошибкой "не удается найти сборку". Я подозреваю, что это связано с более ранней проблемой блокировки, поскольку разработчики запускаются прямо перед сборкой, но внесение любых изменений и перестроек приведет к тому, что все дизайнеры будут рушаться с этой ошибкой (даже те, которые у меня открыты и как текущее представление).

Жалко видеть форму, близкую к экрану ошибок, только потому, что вы изменили "манекен = 1" на "манекен = 2", где "dummy" ничего не делает, кроме как перекомпилировать в полностью несвязанной сборке.

Обновление: я попробовал еще несколько средств: Включить .NET source stepping не проверено, так что это не проблема. Удаление .SUO(параметры пользователя решения) просто работает до тех пор, пока перезагрузка обычно удаляет проблему (две сборки: первая, потому что нет заблокированного файла, а второй, потому что есть один, но его можно переименовать с помощью script).

Error   28  Unable to copy file "obj\Debug\PolicyTracker3.exe" to "bin\Debug\PolicyTracker3.exe". 
The process cannot access the file 'bin\Debug\PolicyTracker3.exe' because it is being used by another process.  

Ответ 1

До тех пор, пока для этого не будет создан патч, у меня есть следующее обходное решение. Просто позвоните, используя что-то вроде "C:\MyBin\VisualStudioLockWorkaround.exe" "$(TargetPath)" (заменив MyBin на место, в которое вы поместите исполняемый файл).

Создайте это как консольное приложение С# и используйте его в разделе Pre-Build так же, как и исходное предварительное переименование (см. верхнюю часть исходного вопроса для деталей).

 using System;
 using System.IO;

 namespace VisualStudioLockWorkaround
 {
  class Program
  {
   static void Main(string[] args)
   {
    string file = args[0];
    string fileName = Path.GetFileName(file);
    string directory = Path.GetDirectoryName(args[0]);
    if (!Directory.Exists(directory)) //If we don't have a folder, nothing to do.
    {
     Console.WriteLine(String.Format("Folder {0} not found. Exiting.", directory));
     return;
    }
    if (!File.Exists(file)) //If the offending executable is missing, no reason to remove the locked files.
    {
     Console.WriteLine(String.Format("File {0} not found. Exiting.", file));
     return;
    }
    foreach (string lockedFile in Directory.EnumerateFiles(directory, "*.locked"))
    {
     try //We know IOExceptions will occur due to the locking bug.
     {
      File.Delete(lockedFile);
     }
     catch (IOException)
     {
      //Nothing to do, just absorbing the IO error.
     }
     catch (UnauthorizedAccessException)
     {
      //Nothing to do, just absorbing the IO error.
     }                                        
    }

    //Rename the executable to a .locked
    File.Move(file, Path.Combine(directory, String.Format("{0}{1:ddmmyyhhmmss}.locked", fileName, DateTime.Now)));
   }
  }
 }

Ответ 2

Там обнаружена ошибка утечки файла с файлом в исходном шаге .NET Framework. Легко избежать, отключив опцию в Инструментах + Опции + Отладчик. Это вряд ли будет вашей проблемой, если вы никогда не получите отладчик.

Непонятно, почему Visual Studio вообще интересовался выходом сборки, не говоря уже о загрузке и блокировке. Может быть, вы однажды открыли .exe? Удалите скрытый файл .suo в каталоге решений. На сайте connect.microsoft.com нет отчета о обратной связи, который бы соответствовал вашей проблеме, я бы рекомендовал вам начать свой собственный. Им потребуется что-то воспроизводимое, чтобы они могли взглянуть на него, убедитесь, что вы включили образец проекта, демонстрирующий это поведение.

Ответ 3

К сожалению, переименование/перемещение заблокированного файла не сработало для меня (ручки были открыты только с FILE_SHARE_READ), но то, что работало, просто убивало эти (предположительно просочившиеся) дескрипторы в процессе Visual Studio. Вы можете использовать KillHandle для автоматизации этого шага.

Ответ 5

В моем случае у меня есть настраиваемая сборка для расширения в Visual Studio 2010, которая работала без проблем в Visual Studio 2008. В какой-то момент сборки некоторые из выходных сборок загружаются в отдельный домен приложения для документации а затем домен разгружается. Разгрузка домена была работоспособной, подтвержденной проверкой списка доменов приложения до и после.

Visual Studio 2010, как представляется, содержит блокировки дескрипторов файлов на любых сборках, загруженных файловыми API-интерфейсами Assembly.Load *, которые работают с файловыми дескрипторами или путями. Я мог видеть, что дескриптор файла появляется в ProcessExplorer, как только Assembly.Load выполняется, и дескриптор никогда не был выпущен даже после того, как AppDomain был выгружен.

Мне удалось решить проблему, загрузив необработанные байты сборки с помощью FileStream и байта [] Assembly.Load overload.

Ответ 6

Я увидел ответ на:

http://social.expression.microsoft.com/Forums/en-US/blend/thread/844dfea0-efa2-440d-97ce-49ac7108dae3

(см. сообщение от Навите Саксена)

Он упоминает о закрытии файлов XAML (поверхности дизайна) и, похоже, работает для меня. Я знаю, что это не все так здорово, но по крайней мере мне не нужно перезапускать VS.

Ответ 7

Я немного опаздываю на вечеринку, но эта проблема возникла впервые после того, как мы обновили VS2015. Это никогда не происходило с VS2010!

Мы часто разрабатываем с одновременным открытием нескольких экземпляров VS - это приложение клиент/сервер, и мы вносим изменения в оба уровня одновременно.

После обновления до VS2015 два экземпляра VS будут "блокировать друг друга" из obj\Debug, и один экземпляр не сможет построить общие ( "общие" ) проекты, то есть нашу DTO, структуру сущности проектов.

Я попробовал pre-build script, и он работал по разным причинам. Это просто не было надежным для нашего случая - иногда dll была настолько заблокирована, что его даже нельзя было переименовать/переместить.

В итоге я просто использовал разные конфигурации построения решений для каждого решения (скопированного из Debug). Это создало новые специализированные каталоги obj и bin для конкретных решений и полностью избегало конфликтов по dll, соответствующих общим проектам.

Надеюсь, это поможет кому-то еще.