Visual Studio блокує вихідний файл під час збірки


80

У мене є просте рішення 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

Провідник процесів показує, що devenv.exe завантажив файл (у DLL-файлах, а не в Handles). Здається, якийсь збій під час збірки перешкоджав розвантаженню, але (перша) збірка завершується без будь-яких повідомлень, тоді як "1 вдалося, про не вдалося" /


іноді у мене виникає подібна проблема; ви використовуєте Windows 7? У моєму випадку це не VS блокування файлу: я можу просто видалити його в провіднику, і збірка працює нормально. Я помітив, що проблема трапляється частіше, якщо у вихідному каталозі відкрито вікно провідника. Не використовується сканер вірусів, крім того.
stijn

Подібна проблема виникає зрідка на Win7 під час використання NUnit, що надзвичайно дратує, коли ви робите деякі TDD.
Матіас

@stijn: Ви не використовуєте вбудований сканер вірусів? Дух ...
TheBlastOne

Це також трапляється у мене з VS 2013, коли я налагоджую модульні тести і зупиняю код до того, як VS завершить виконання тесту. Якщо я почекаю додаткові кілька секунд, поки VS вивантажить тест-драйвер, цього не відбувається.
StingyJack

Можливо, це допоможе: sevenforums.com/tutorials/…
Saturn Technologies

Відповіді:


69

Мав ту саму проблему, але знайшов рішення (завдяки Кейвану Найєрі ):

Але як це вирішити? Існують різні способи, засновані на типі вашого проекту, але одне просте рішення, яке я рекомендую розробникам надбудови Visual Studio, - це додати простий код до подій збірки їх проекту.

Ви можете додати наступні рядки коду до командного рядка події попередньої збірки вашого проекту.

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

Працював і у мене. Маю цю проблему вже якийсь час.
ritcoder 02

Це працює для мене. Я спробував версію% random% цього згідно з Володимиром Дацюком нижче, але виявив, що в моєму випадку єдиний файл, який блокується, - це з першої збірки після запуску VS, тому він повинен працювати лише один раз. Я перебуваю на VS 2013, і я також не використовую дизайнер gui, це просто велике рішення з безліччю посилань та проектів шаблонів T4.
Давос

5
Мені потрібно перейменувати PDB теж, як вона була замкнена також: if exist "$(TargetDir)$(TargetName).pdb.locked" del "$(TargetDir)$(TargetName).pdb.locked" ,if exist "$(TargetDir)$(TargetName).pdb" if not exist "$(TargetDir)$(TargetName).pdb.locked" move "$(TargetDir)$(TargetName).pdb" "$(TargetDir)$(TargetName).pdb.locked"
Tobias J

Працює і для мене (Visual Studio 2013). Thx
Анонім

Продовжує працювати над VS2017. Що дивно, так це те, що проблема зберігається у VS2017!
Carvo Loco

24

Це не проблема вірусів. Це помилка 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 рази.


1
Це трапляється і зі мною, але лише за умови запуску програми. Я підозрюю, що це ОС, яка стежить за виконуваним файлом з кешування або з інших причин. Крім того, здається, це відбувається лише для програм, які викликають System.Reflection.Assembly.GetExecutingAssembly (), принаймні в моєму випадку.
TheBlastOne

2
Добре, здається, це трапляється лише в тому випадку, якщо останній запуск називається System.Reflection.Assembly.GetExecutingAssembly, або -і це новина- якщо є вихідний код будь-якого компонента проектування (вихідний код будь-якого компонента часу проектування, який активний на панелі інструментів компонента) що робить виклик System.Reflection.Assembly.GetExecutingAssembly під час проектування був відкритий у редакторі, коли стартував останній запуск. Зрозумів?
TheBlastOne

1
Я думаю, що ця проблема раптово з’явилася ... Зараз я витратив 30 хвилин свого життя, намагаючись створити проект проекту .. тому що у мене виникають проблеми з блокуванням! Я навіть не запускаю програму ..
GorillaApe

1
stackoverflow.com/questions/3312646/…, який працював у мене
GorillaApe

1
Додатково для файлу pbd: del "$(TargetPath).locked.*" /q if exist "$(TargetPath)" move "$(TargetPath)" "$(TargetPath).locked.%random%" del "$(TargetDir)$(TargetName).pdb.locked.*" /q if exist "$(TargetDir)$(TargetName).pdb" move "$(TargetDir)$(TargetName).pdb" "$(TargetDir)$(TargetName).pdb.locked.%random%" exit /B 0
Marv

6

Проблема виникла і в мене.

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

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

Повідомте мене, якщо це допомогло і вам. Удачі.


1
У мене була така сама проблема у всіх випусках VS11, але мені ще не вдалося знайти виправлення (на жаль, допомога без прав адміністратора не допомогла). Будь-які ідеї оцінені!
Ден Нолан

4

Я бачив це в жадібному програмному забезпеченні для сканування вірусів, або якщо app.exe не вимикається належним чином. Переконайтеся, що процес все ще не запущений.


3

А як щодо сканерів вірусів на вашому комп'ютері? Чи можете ви побачити будь-які процеси, які утримують дескриптори вашого файлу (використовуйте Провідник процесів щоб дізнатися)?

Можливо, у вашому списку процесів видно "app.exe", тобто остання версія, яку ви налагодили, все ще працює? Коли ви розробляєте програми, які мають кілька потоків, це може статися, якщо ви не joinвсі з них.


3

У мене була та ж проблема, і я дізнався, що VS блокує exe лише тоді, коли перед створенням я відкрив у VS форму або UserControl. Рішення було досить простим, мені просто довелося закрити будь-яку форму / UserControl, перш ніж будувати рішення, і воно спрацювало.


3

Підстава на великий Stormenet відповідь , я поклав на невеликий скрипт , який повинен працювати в усіх випадках.

Ось код, який потрібно помістити в текстове поле події попередньої збірки

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

Подія попередньої збірки

Ось сценарій для копіювання у файл $(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%"

2

Існує також відома проблема 533411, коли використання автоматичного оновлення номерів збірки може спричинити проблему блокування. Вирішення із звіту про помилку

Тимчасовим рішенням буде вимкнення оновлення версії збірки після відновлення. У файлі AssemblyInfo.cs видаліть підстановку з атрибута AssemblyVersion, наприклад:
замініть це:
[Assembly: AssemblyVersion ("1.4. *")]
[Assembly: AssemblyFileVersion ("1.4")]
на:
[Assembly: AssemblyVersion ("1.4.0.0")]
[збірка: AssemblyFileVersion ("1.4.0.0")]


2

У мене була ця проблема, і я вирішив її за допомогою власного коду. Дивіться тут: Проблеми із блокуванням файлів збірки Visual Studio 2010

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

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


0

Єдине, що мені вдалося, це вийти з Visual Studio 2012, видалити папки BIN та OBJ для проекту, що має проблеми, і знову відкрити Visual Studio.

Проблема вирішена ... До наступного разу.


0

Якщо ваш $ (TargetPath) вказує на DLL, яка використовує COM, переконайтеся, що у вас є конструктор за замовчуванням. Не впевнений, чому конструктор за замовчуванням там не виведений. Додавання конструктора за замовчуванням спрацювало для мене в цьому сценарії.


0

Закриття візуальної студії, повторне відкриття та перезавантаження останнього рішення для мене вирішує проблему. (Visual Studio 2013 Ultimate)


1
Так, мені доводиться це робити щоразу. це не рішення
Джон Деметріу

0

Я зіткнувся з тим самим, що розробляв програми xamarin у VS2017.

Випадково Windows Defender блокував exe / dll за допомогою devenv.exe.

Ви можете перейти до Win Defender і додати

devenv.exe
msbuild.exe

до списку виключень процесу.


як ви дізналися, що це захисник Windows?
Майк

моє рішення трохи попрацювало, але я з’ясував, що насправді це серйозна помилка в новому випуску оновлення VS2017 для мене. developercommunity.visualstudio.com/content/problem/54945/…
Майкл Г

0

Це рішення я знаходжу

  1. Зніміть прапорець із хостингу Visual Studio у налаштуваннях проекту, як показано нижче

введіть тут опис зображення

  1. Убити колишнього. це буде ваше ім'я програми.vshost.exe від taskmanager

введіть тут опис зображення

  1. Тепер ви можете відновити свою програму та запустити.

Примітка: Ви можете знову ввімкнути цю опцію без проблем.


0

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

Потім я, звичайно, продовжив повністю видаляти McAfee, який було встановлено лише тому, що мій ПК новий, і він постачався з уже встановленою програмою.


-8

Я створив нове порожнє рішення і додав до нього всі старі файли. Це якось вирішило проблему.


Це не може бути відповіддю. Інші надали набагато чіткіші причини проблеми та відповідні обхідні шляхи, які не вимагають створення нового файлу рішення, що неприпустимо під час роботи з контролем версій, оскільки історія буде втрачена.
Бернхард Хофманн,

Так, це погана відповідь. Інші гірші. Перейменування вихідних файлів не є рішенням, це громіздке рішення. Якщо у вас є кращі ідеї, чому б не опублікувати відповідь?
Неважливо

Створення нового рішення лише тимчасово вирішило проблему для мене. Здається, найкращою є відповідь Володимира Дацюка.
user492238

1
Чи буде це ваше рішення оптимальним, якщо у вас є близько 15 проектів в одному рішенні?
Shittu Joseph Olugbenga
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.