Visual Studio блокирует выходной файл при сборке - PullRequest
77 голосов
/ 05 января 2010

У меня есть простое решение WinForms в VS 2010. Всякий раз, когда я его собираю, выходной файл (bin \ debug \ app.exe) блокируется, и последующие сборки терпят неудачу с таким сообщением, как "The process cannot access the file 'bin\Debug\app.exe' because it is being used by another process." Единственный способ построить проект - перезапускать VS после каждой сборки, что очень неловко.

Я нашел это старое сообщение в блоге http://blogs.geekdojo.net/brian/archive/2006/02/17/VS2005FileLocking.aspx - похоже, проблема действительно старая. Кто-нибудь знает, что здесь происходит, или хотя бы какой-нибудь обходной путь?

Обновление

На самом деле я не запускаю файл. Блокировка происходит после сборки, а не после отладки (то есть запуск VS - сборка - сборка - ошибка!) И я попытался отключить антивирус. Это не помогает.

Обновление 2

Process Explorer показывает загрузку файла devenv.exe (в DLL, а не в Handles). Кажется, что какой-то сбой во время сборки предотвратил выгрузку, но (первая) сборка завершается без каких-либо сообщений, кроме «1 успешно завершено, o не удалось» /

Ответы [ 16 ]

68 голосов
/ 29 апреля 2010

Была такая же проблема, но нашел решение (спасибо Keyvan Nayyeri ):

а как это решить? Существуют различные способы, основанные на типе вашего проекта, но одно простое решение, которое я рекомендую разработчикам надстроек Visual Studio, - это добавление простого кода в события сборки их проекта.

Вы можете добавить следующие строки кода в командную строку вашего проекта перед сборкой.

if exist "$(TargetPath).locked" del "$(TargetPath).locked"
if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"
24 голосов
/ 14 октября 2010

Это не проблема вируса. Это ошибка Visual Studio 2010. Кажется, проблема связана с использованием визуального дизайнера графического интерфейса студии.

Обходной путь - переместить заблокированный выходной файл в другой временный файл в событии перед сборкой Имеет смысл генерировать временные имена файлов случайным образом.

del "$(TargetPath).locked.*" /q 
if exist "$(TargetPath)"  move "$(TargetPath)" "$(TargetPath).locked.%random%"
exit /B 0

В случае использования постоянных временных имен файлов вы просто откладываете блокировки:

Этот обходной путь срабатывает ровно один раз

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

Я также нашел решение с 2 временными файлами, которое работает ровно 2 раза.

5 голосов
/ 24 мая 2012

Проблема возникла и у меня тоже.

Мой сценарий был такой: запуск Windows 7 (но может также случиться в Windows XP), и во время работы над проектом с WPF User Control я мог строить все время, до открытия XAML-файла User Control - оттуда У меня одна сборка, а затем файлы заблокированы.

Кроме того, я заметил, что я запускал Visual Studio (Devenv.exe) в качестве администратора, Я начал запускать Visual Studio без прав администратора, и проблема исчезла! .

Дайте мне знать, если это вам тоже помогло. Удачи.

3 голосов
/ 04 марта 2016

Основываясь на большом Ответе Стормене , я поставил небольшой скрипт, который должен работать во всех случаях.

Вот код, который нужно вставить в текстовое поле события перед сборкой

$(SolutionDir)\BuildProcess\PreBuildEvents.bat  "$(TargetPath)"  "$(TargetFileName)"  "$(TargetDir)"  "$(TargetName)"

Pre build event

Вот скрипт для копирования в файл $(SolutionDir)\BuildProcess\PreBuildEvents.bat (конечно, вы можете изменить этот путь):

REM This script is invoked before compiling an assembly, and if the target file exist, it moves it to a temporary location
REM The file-move works even if the existing assembly file is currently locked-by/in-use-in any process.
REM This way we can be sure that the compilation won't end up claiming the assembly cannot be erased!

echo PreBuildEvents 
echo  $(TargetPath) is %1
echo  $(TargetFileName) is %2 
echo  $(TargetDir) is %3   
echo  $(TargetName) is %4

set dir=C:\temp\LockedAssemblies

if not exist %dir% (mkdir %dir%)

REM delete all assemblies moved not really locked by a process
del "%dir%\*" /q

REM assembly file (.exe / .dll) - .pdb file - eventually .xml file (documentation) are concerned
REM use %random% to let coexists several process that hold several versions of locked assemblies
if exist "%1"  move "%1" "%dir%\%2.locked.%random%"
if exist "%3%4.pdb" move "%3%4.pdb" "%dir%\%4.pdb.locked%random%"
if exist "%3%4.xml.locked" del "%dir%\%4.xml.locked%random%"

REM Code with Macros
REM   if exist "$(TargetPath)"  move "$(TargetPath)" "C:\temp\LockedAssemblies\$(TargetFileName).locked.%random%"
REM   if exist "$(TargetDir)$(TargetName).pdb" move "C:\temp\LockedAssemblies\$(TargetName).pdb" "$(TargetDir)$(TargetName).pdb.locked%random%"
REM   if exist "$(TargetDir)$(TargetName).xml.locked" del "C:\temp\LockedAssemblies\$(TargetName).xml.locked%random%"
3 голосов
/ 17 февраля 2011

У меня была такая же проблема, и я обнаружил, что VS блокирует исполняемый файл, только когда я открыл Form или UserControl в VS перед сборкой. Решение было довольно простым, мне просто пришлось закрыть любой Form / UserControl, прежде чем я собрал решение, и оно заработало.

3 голосов
/ 05 января 2010

Я видел это либо в программном обеспечении для проверки на жадность вирусов, либо если app.exe не завершает свою работу должным образом Убедитесь, что процесс еще не запущен.

3 голосов
/ 05 января 2010

А как насчет вирусных сканеров на вашем компьютере? Можете ли вы увидеть какие-либо процессы, которые содержат дескрипторы в вашем файле (используйте Process Explorer , чтобы узнать)?

Может быть, в вашем списке процессов виден «app.exe», т.е. последняя отлаженная версия все еще работает? Когда вы разрабатываете приложения с несколькими потоками, это может произойти, если вы не join все из них.

2 голосов
/ 14 октября 2010

У меня была эта проблема, и я решил ее с помощью специального кода. См. Здесь: Проблемы блокировки файла сборки Visual Studio 2010

Скомпилируйте утилиту в принятом ответе и сделайте ссылку на нее на этапе сборки, как описано, чтобы обойти проблему. Я все еще выключаю VS 2010 на обед, чтобы очистить утреннюю работу.

Причиной использования нестандартного кода было то, что часто рекомендуемое решение работало только один раз, а затем переименованные файлы также блокировались, предотвращая переименование. Здесь мы просто добавляем информацию о времени данных в файл, чтобы переименованные версии не могли конфликтовать.

2 голосов
/ 09 сентября 2010

Существует также известная проблема 533411 , когда использование автоматического обновления номеров сборок может вызвать проблему блокировки. Обходной путь из сообщения об ошибке

Временный обходной путь - отключить обновление версии сборки после восстановления. В файле AssemblyInfo.cs удалите подстановочный знак из атрибута AssemblyVersion, например:
замени это:
[сборка: AssemblyVersion ("1.4. *")]
[сборка: AssemblyFileVersion ("1.4")]
с этим:
[сборка: AssemblyVersion ("1.4.0.0")]
[Assembly: AssemblyFileVersion ("1.4.0.0")]

0 голосов
/ 06 октября 2017

Мне удалось решить эту проблему, отключив McAfee LiveSafe в режиме реального времени. Мой файл .exe блокировался, как описывает OP, и у меня не было бы возможности удалить файл, а это означало, что я не смог построить решение. После отключения функции McAfee проблема исчезла.

Затем я, конечно же, полностью удалил McAfee, который был установлен только потому, что у меня новый компьютер, и он шел с уже установленной программой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...