none
Dll не загружена, хоть она рядом с exe. RRS feed

  • Вопрос

  • Создал приложение, добавил в проект dll.
    dll файл раздавал вместе с exe в том же каталоге.

    Всё как обычно.
    Но, на одном из компьютеров, выскочила эта ошибка:

    ************** Exception Text **************
    System.IO.FileLoadException: Could not load file or assembly 'HtmlAgilityPack, Version=1.4.0.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)
    File name: 'HtmlAgilityPack, Version=1.4.0.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a' ---> System.Security.SecurityException: Strong name validation failed. (Exception from HRESULT: 0x8013141A).
    ну и тд.
    Проверили, dll лежит там где и должна, рядом с exe.

    Как выяснилось, если добавить в GAC эту dll-ку через gacutil, то программа будет работать,
    хоть почему-то картинка, что была задним фоном формы не отображалась после этого.

    Как так?, dll нужна только той программе, значит судя по всяким там книгам и сайтам в gac не надо добавлять.
    Где баг? В книгах/сайтах, или в том как я читаю их?

    Подскажите пожалуйста.

    Может надо всегда в gac добавлять?, или ещё какие-то действия делать.
    Даже если dll нужна только для одной программы.
    • Изменено INFEL8 3 июня 2012 г. 12:54
    3 июня 2012 г. 12:51

Ответы

  • Если библиотека повреждена, и не загружалась из папки с приложением, то и из GAC'а она не загрузится. Никак.

    Сложно гадать на расстоянии. А не мог никто манифест подправить? Может там админ учудил что-нибудь. Но это только вам знать, кто и что там мог сделать.

    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 8:23
  • Судя по ошибке, загрузка не удалась, потому что не прошла валидация подписи сборки (строгое имя).

    Возможно, на том компьютере, где возникла ошибка, уже была эта библиотека, причём подписанная другим ключом, и именно её пыталась загрузить программа. Естественно, загрузка не удалась.

    Однако, сложно понять, как такое могло произойти. Ведь, насколько я помню, по умолчанию сперва ищется библиотека в той же папке, где расположена запускаемая программа. И если вы не меняли эту dll, то именно она и должна грузиться.

    Возможно, при копировании эта dll была повреждена. Ну, мало ли - повреждённый сектор на жёстком диске или ещё что. Или вирус поработал. При изменении хоть одного бита подписанной сборки её загрузка будет отвергаться. Безопасность CLR на высоте!

    А в GAC добавлять сборку необязательно. Это желательно делать если только одна и та же сборка будет использоваться разными программами. То есть, если будет у вас несколько программ, и все будут использовать, например, ту же HtmlAgilityPack.dll, вот тогда эту dll можно установить в GAC, чтобы не было лишнего дублирования. Впрочем, можно прописать путь к используемой библиотеки (библиотекам) и вне GAC'а.

    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 8:22
    5 июня 2012 г. 21:47
  • Возможно что на проблемной машине битый диск/память, и ваша dll просто повредилась при инсталле в папку. Попробуйте скопировать ее обратно, и сравнить с оригиналом, через fc /b.
    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 8:23
    6 июня 2012 г. 10:38
  • >> Совершенно верно.

    Не совсем. При загрузке сборок из GAC пропускается верификация Strong Name. Она происходит в момент добавления в GAC, но если добавляли не из папки приложения (где лежит явно битая dll), а отдельно скачанную/присланную копию - то вести себя приложение будет именно так, как описано топикастером.

    >> Но вот вариант: если другое приложение будет использовать ту-же разделяемую сборку в GAC и обновит её при установке, проблема получается.

    Только если разработчики этой сборки пойдут против правил, и не обновят номер версии при выпуске. Очень маловероятно для HtmlAgilityPack, у которого 300к закачек на Codeplex. 

    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 8:23
    7 июня 2012 г. 10:45

Все ответы

  • Судя по ошибке, загрузка не удалась, потому что не прошла валидация подписи сборки (строгое имя).

    Возможно, на том компьютере, где возникла ошибка, уже была эта библиотека, причём подписанная другим ключом, и именно её пыталась загрузить программа. Естественно, загрузка не удалась.

    Однако, сложно понять, как такое могло произойти. Ведь, насколько я помню, по умолчанию сперва ищется библиотека в той же папке, где расположена запускаемая программа. И если вы не меняли эту dll, то именно она и должна грузиться.

    Возможно, при копировании эта dll была повреждена. Ну, мало ли - повреждённый сектор на жёстком диске или ещё что. Или вирус поработал. При изменении хоть одного бита подписанной сборки её загрузка будет отвергаться. Безопасность CLR на высоте!

    А в GAC добавлять сборку необязательно. Это желательно делать если только одна и та же сборка будет использоваться разными программами. То есть, если будет у вас несколько программ, и все будут использовать, например, ту же HtmlAgilityPack.dll, вот тогда эту dll можно установить в GAC, чтобы не было лишнего дублирования. Впрочем, можно прописать путь к используемой библиотеки (библиотекам) и вне GAC'а.

    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 8:22
    5 июня 2012 г. 21:47
  • То есть, предположим, что библиотека немного повреждена, но не достаточно, чтобы не работала после внесения её же в GAС.
    Тогда всё равно не понятно, почему она не загружается из каталога, где exe файл,
    а всё-таки работает через GAC.

    Тот, кто посоветовал добавить в GAC, предположил, что может быть как-то прав не хватило для загрузки dll из каталога приложения.
    Установка шла через Installer,
    там может быть получились какие-то другие права относительно того как запускать.
    Конечно, это всё было бы тоже странно, но кто же его знает...
    В любом случае, я ожидал что библиотека загрузится из каталога приложения, тем более, что ссылку на неё так и устанавливал.

    ПС. На том компьютере вроде бы Windows XP. Точно не знаю.

  • Если люди предполагали о проблеме с правами, то возможно так и есть. Вы сейчас не сможете проверить оставив dll только в папке с программой и убрать из GAC. Потом запустить программу от имени администратора. Если с работает, то одна функций dll требует повышенных привилегий.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    Отвечающий
  • "Как так?, dll нужна только той программе, значит судя по всяким там книгам и сайтам в gac не надо добавлять. Где баг? В книгах/сайтах, или в том как я читаю их?" - если Вашу сборку должа использовать только одна программа, то не зачем делать её разделяемой, компилируёте её как приватную и избавьтесь от лишних проблем. И в случае с приватной сборкой можно воспользоваться всеми преимуществами теневого копирования (Xcopy).

    "Может надо всегда в gac добавлять?, или ещё какие-то действия делать. Даже если dll нужна только для одной программы." - нет, не нужно, как уже отметил высше, используйте приватные сборки (компилируйте её как приватную).

    А что касается ошибки, то при помощи IL Disassembler загляните в манифест вашей исполняемой сборки (вашего exe файла )  и сравните номер, версию  и строгое имя, указанное там для вашей dll которая не загружается, с данными вашей dll. Может быть , что dll была скомпилирована отдельно, такое бывает, поэтому и номера версии могут не совпадать. Или как уже было предложено высше, может, и повреждена.

    Модератор
  • Возможно что на проблемной машине битый диск/память, и ваша dll просто повредилась при инсталле в папку. Попробуйте скопировать ее обратно, и сравнить с оригиналом, через fc /b.
    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 8:23
    6 июня 2012 г. 10:38
  • До туда очень трудно достучаться,
    через пятые-десятые лица только.
    Попробую конечно, но я думаю не особо будут пробовать, работает ведь после внесения в гак.
    В общем предположительно скорее всего dll повреждена (судя по единогласию отвечающих).
    Посмотрим ответят ли мне где не сразу пошло.

  • dll просто скачана с сайта (значит скомпилирована отдельно).
    это сторонняя dll. Потом просто добавлена к проекту по ссылке.

  • Вас уже не понять, то Вы говорите что dll эта только для вашего приложения и распространяется только вместе с ним и только для него. А теперь, что это чужая библиотека и компилируется отдельно. Тогда ничего удивительного, что верификация может не проходить.
    Модератор
  • Одно другому не мешает.

    Компонент скачан с сайта, уже скомпилированный.
    Нужен только для этого приложения., потому и располагается в папке приложения.

    • Изменено INFEL8 7 июня 2012 г. 8:22
  • Как показывает практика иногда мешает. Ну я конечно не знаю, что там у Вас на самом деле. Но вот вариант: если другое приложение будет использовать ту-же разделяемую сборку в GAC и обновит её при установке, проблема получается.
    Модератор
  • Я наверное чего-то не понимаю, может даже как работает со сборками это всё,
    но разве не должна библиотека браться из папки приложения, если она там есть?
    при том ссылка была установлена именно на неё.
    Если так, то проблемы быть не должно вроде бы.
    Значит наверное что-то я недопонимаю например по причине, что не те книги/сайты читал (ну или не так).

  • "но разве не должна библиотека браться из папки приложения, если она там есть?" - должна в случае с приватной, и во время разделяемой тоже, если её нет в GAC. "Если так, то проблемы быть не должно вроде бы." - не должно, вверху были предположения, что она повреждена скорее всего. Просто нужно было с самого начала в вопросе указать, что это не ваша сборка.
    Модератор
  • Учту, не предполагал, что это может быть важно.
    В общем нужно чтобы они у себя проверили на повреждения.
    Но если она повреждена, то как она может загрузиться после отправки в GAC?
    Может случиться так, что она повреждена, но не на столько, чтобы не загружаться из GAC?
  • Если библиотека повреждена, и не загружалась из папки с приложением, то и из GAC'а она не загрузится. Никак.

    Сложно гадать на расстоянии. А не мог никто манифест подправить? Может там админ учудил что-нибудь. Но это только вам знать, кто и что там мог сделать.

    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 8:23
  • Если библиотека повреждена, и не загружалась из папки с приложением, то и из GAC'а она не загрузится. Никак.

    Сложно гадать на расстоянии. А не мог никто манифест подправить? Может там админ учудил что-нибудь. Но это только вам знать, кто и что там мог сделать.

    Совершенно верно.
    Модератор
  • >> Совершенно верно.

    Не совсем. При загрузке сборок из GAC пропускается верификация Strong Name. Она происходит в момент добавления в GAC, но если добавляли не из папки приложения (где лежит явно битая dll), а отдельно скачанную/присланную копию - то вести себя приложение будет именно так, как описано топикастером.

    >> Но вот вариант: если другое приложение будет использовать ту-же разделяемую сборку в GAC и обновит её при установке, проблема получается.

    Только если разработчики этой сборки пойдут против правил, и не обновят номер версии при выпуске. Очень маловероятно для HtmlAgilityPack, у которого 300к закачек на Codeplex. 

    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 8:23
    7 июня 2012 г. 10:45
  • В общем, что удалось всё-таки выяснить:
    dll в GAC отправлялась именно та, что была в папке приложения. (куда её отправил инсталлер).
    Эта dll не повреждена, если сравнивать той командой, что тут дали.
    Манифесты просмотрел (мне прислали архив с установленной програмой),
    сравнил GUID и keytoken, всё 1 в 1 и в exe файле и в dll.
    То же самое и в старых версиях и в новых, всё одинаково тут.

    Запустить с правами админа выпросить не удалось, так что не проверил..

    Но вот новая подробность:
    Более старая версия программы, что там была, оказывается, до того,
    запускалась и запускается и работает без проблем (конечно, если всё правильно мне сказали).
    В той версии не приходилось в GAC вносить, и без тогго работало нормально.

    А новая версия, если dll для неё тоже не вносить в GAC, не работает.


    • Изменено INFEL8 8 июня 2012 г. 11:24
    8 июня 2012 г. 11:23
  • Появилась новая информация.
    Меня немного дезинформировали по поводу того какую dll вносили в gac.

    dll оказалась повреждена, изменены 4 байта.
    Что интересно, у меня с изменённой и неизменённой библиотекой работает одинаково без сбоев.
    Есть информация почему так?
    получается только на том компьютере безопасность на высоте...

    13 июня 2012 г. 5:39
  • Появилась новая информация.
    Меня немного дезинформировали по поводу того какую dll вносили в gac.

    dll оказалась повреждена, изменены 4 байта.
    Что интересно, у меня с изменённой и неизменённой библиотекой работает одинаково без сбоев.
    Есть информация почему так?
    получается только на том компьютере безопасность на высоте...

    А вы уверены, что у вас не измененная версия не имеет приоритета над измененной?  Может когда вы думаете что работает одна, на деле работает другая. Кстати это можно отследить по средством программы procmon

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    13 июня 2012 г. 5:42
    Отвечающий
  • У меня в GAC не внесена она,
    просто переименовал одну библиотеку (0 приписал),
    скопировал туда вторую с обычным именем, и запустил.

    13 июня 2012 г. 5:46
  • "Меня немного дезинформировали по поводу того какую dll вносили в gac. dll оказалась повреждена, изменены 4 байта." - значит всё-таки повреждена была, как и предполагали неоднократно. Дезинформация - это плохо.

    13 июня 2012 г. 6:07
    Модератор