Справочник .NET «Копировать локальный» Истина / Ложь устанавливается на основе содержимого GAC - PullRequest
16 голосов
/ 20 марта 2010

У нас была очень интересная проблема с проектом Win Forms.Это было решено.Мы знаем, что случилось, но мы хотим понять, почему это произошло.В будущем это может помочь другим людям, у которых возникла подобная проблема.

Проект WinForms провалился на 2 компьютерах нашего клиента.Ошибка была неясной ошибкой kernel.dll.Проект работал нормально на 3 других компьютерах.

Мы обнаружили, что .DLL (log4net.dll - очень популярная библиотека журналов с открытым исходным кодом) отсутствует в нашей папке выпуска.Это было ранее в нашей папке выпуска.Почему это отсутствовало в этом последнем выпуске?

Это отсутствовало, потому что я, должно быть, установил на своем компьютере разработчика программу, которая использовала log4net.dll, и она была добавлена ​​в глобальный кэш сборок.

Когда я проверил ссылки решения для log4net.dll, они были изменены на «copy local = FALSE».Они должны были измениться автоматически, потому что log4net.dll присутствовал в моем GAC.

Вот где начинается мой вопрос:

Почему моя ссылка на log4net.dll была изменена с COPY LOCAL = TRUE на COPY LOCAL = FALSE?Я подозреваю, что это потому, что он был добавлен в мой GAC другой программой.

Как мы можем предотвратить это снова?В настоящее время, если я устанавливаю часть программного обеспечения, которая использует общую библиотеку, и добавляет ее в мой GAC, то мои SLN, которые ссылаются на эту DLL, изменятся с Copy Local TRUE на FALSE.

Ответы [ 5 ]

6 голосов
/ 20 марта 2010

Это произошло потому, что не имеет смысла иметь Copy Local = True, если сборка установлена ​​в GAC. Поскольку эта локальная копия никогда не будет использоваться, GAC всегда ищется первым. Если оставить его без изменений, это может привести к путанице: вы можете подумать, что используете локальную копию, но вместо этого получите другую. Его изменение также вызывает путаницу, если вы ее не замечаете, возможно, это можно было бы устранить с помощью окна сообщения во время загрузки решения.

Log4net является источником проблем, слишком много версий в дикой природе без какой-либо процедуры развертывания, которая гарантирует, что эти версии не кусают друг друга. Что-то, по-видимому, Apache просто не хотел решать, оставив это на усмотрение программиста. Наличие продуктов, которые зависят от Log4net и что-то делают с предполагаемым риском DLL Hell, несколько неизбежно. Взамен вам проблема с DLL-адом.

Нет простых простых ответов, кроме знания того, что установлено на вашем компьютере. Подумайте о публикации на connect.microsoft.com с запросом предупреждения, когда Visual Studio автоматически обновляет свойство «Копировать локально». Это разумный вопрос.

3 голосов
/ 29 января 2016

Я нашел решение для нас на наших серверах сборки.

Проблема: В конкретную дату без причины (теперь я предполагаю, что файл был добавлен в GAC) сборка System.Web.MVC.dll исчезла из многих наших проектов. Я уверен, что это относится к любой DLL с проблемой.

Решение: В visual studio измените ссылку (при условии, что Copy Local уже True).

  1. Изменить Локальное копирование = True на Локальное копирование = False
  2. Изменить Локальное копирование обратно на True
  3. Примечание. В файле .csproj добавлен <Private>True</Private>.
  4. Скомпилируйте сейчас, и вы увидите, что DLL действительно включается, даже если сообщение остается прежним.

Solution2: Добавьте свойство <private>True</private> вручную.

Выводы: Насколько я понимаю, <Private> - это Копия локальная, поэтому если Копировать локально = True, то следует добавить свойство Private, но по крайней мере в нашем случае это не так.

Дополнительные замечания:

  1. Протестировано с использованием Visual Studio 2013 и 2015.
  2. Протестировано с использованием msbuild 12 и 14.
  3. Протестировано с использованием шаблона сборки TFS.
  4. Наш код был обновлен с 2008 по 2015 гг. Visual Studio, флаг мог быть испорчен где-то в это время, но проблема не началась, пока сборка не была каким-то образом добавлена ​​в GAC.

Конечный результат:

<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral,PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
 <HintPath>packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll        </HintPath>
        <Private>True</Private>
    </Reference>
2 голосов
/ 29 апреля 2010

Во время выполнения сборки должны находиться в одном из двух мест: выходной путь проекта или глобальный кэш сборок (см. Работа с сборками и глобальный кэш сборок). Если проект содержит ссылку на объект, который не находится в одном из этих мест, то при создании проекта ссылка должна быть скопирована в выходной путь проекта. Свойство CopyLocal указывает, нужно ли делать эту копию. Если значение равно true, ссылка копируется. Если false, ссылка не копируется.

Назначенное проектом значение CopyLocal определяется в следующем порядке:

  1. Если ссылка - это другой проект, называемый ссылкой «проект-проект», то значение равно true.
  2. Если сборка найдена в глобальном кэше сборок, значение равно false.
  3. В особом случае значение для ссылки mscorlib.dll равно false.
  4. Если сборка находится в папке Framework SDK, то значение равно false. В противном случае значение равно true.

С уважением ... Muse VSExtensions

1 голос
/ 16 июня 2010

Я только что столкнулся с этой проблемой и на наших серверах сборки. Это очень раздражающее (и неожиданное) поведение Visual Studio. Два обходных пути:

  1. Удалите сборки из GAC.
  2. Добавьте событие PostBuild, чтобы вручную скопировать сборки в выходной каталог.
0 голосов
/ 20 марта 2010

Можете ли вы убедиться, что ваш используется, добавив hintpath в файл msbuild / proj?

Из приведенной выше ссылки:

HintPath : относительный или абсолютный путь сборки .

...