Развертывание приложения WPF с помощью DLL сторонних производителей

Я был крайне расстроен, пытаясь развернуть приложение С#/WPF, которое я создал, которое имеет некоторые ссылки на сторонние DLL. Я создал папку в проекте под названием lib, где я разместил все эти DLL. В VS2012 я добавил ссылки, перейдя в эту папку и выбрав все библиотеки DLL. Copy Local для true. Все хорошо, когда я строю и запускаю, но когда я выбираю публикацию и создаю установщик OneClick, все не так гладко. Во время публикации мастера я установил его для установки с диска и установил, чтобы он никогда не проверял наличие обновлений. Я беру эту папку, размещаю ее на флеш-накопителе, подключаю ее к другому компьютеру, запускаю настройку и выбрасываю исключение. Я считаю, что знаю, что происходит, но я не могу понять, как это сделать, чтобы правильно его развернуть.

Одна из моих DLL - это оболочка С# для DLL, предназначенная для проекта С++. Скажем, Application требует DLL1 и DLL1 требует DLL2. DLL2 не может быть добавлено как ссылка в проекте, потому что это не .NET DLL. DLL1 требует, чтобы DLL2 находился в одной папке, чтобы забрать его. Я использую CefSharp, который обертывает Chromium Embedded Framework.

Я попытался разместить требуемые DLL для CefSharp.dll в каталоге publish/Application Files, но это не сработало. Я заметил, что все DLL файлы, которые есть у VS2012, имеют расширение .deploy, я даже пошел и добавил это расширение, чтобы проверить, было ли это сканирование для этого, но оно тоже не работает. Это мой первый опыт разработки и развертывания для приложения Windows, и все обучающие материалы на MSDN или сообщениях в блоге, которые я прочитал, похоже, не охватывают этот случай, и я не вижу других параметров в диспетчере развертывания для обработки этих типы случаев.

Если это помогает, генерируемый код исключения: CLR20r3

Когда я поймаю и покажу Exception, вся информация, которую я предоставляю, в основном говорит CefSharp.dll or one of it dependencies cannot be loaded. Который я получил раньше, когда DLL2 не был в той же папке, что и DLL1.

Может ли кто-нибудь предоставить помощь по развертыванию из VS2012 с такой ситуацией?

Спасибо заранее!

Изменить: обновление информации

Я пытался вытолкнуть версию отладки на тестовую машину без установки Visual Studio. При построении для CefSharp или любого другого С++ Runtime DLL он будет искать все версии отладки DLL, которые обычно имеют одно и то же имя, но с буквой "d", добавленной в конец. Как упоминалось ниже, версия Debug С++ Runtime не распространяется. Не то, чтобы вы не могли вручную добавить эти DLLs в свой проект и установить их как Copy Always, но такую ​​работу взлома. Я начал новый проект с нуля, добавил все версии версий DLL, построил, и все было в порядке.

Ответ 1

Я разорвал свои волосы, пытаясь решить эту проблему сегодня утром, и в итоге нашел решение. Кажется, вы уже знаете, какие DLL и т.д. Вам нужны для работы CEFSharp, но я подумал, что я пропустил бы это, если у кого-то будет такая же проблема. У меня есть приложение С# WPF, и я использую CEFSharp в качестве веб-представления. Я использую CEFSharp v1, потому что мне нужен модуль JavaScript → С#, который они предоставляют, который еще не реализован в v3. Вот грубые шаги, которые я провел при настройке проекта (я использую VS2013, но это, вероятно, будет работать в VS2012).

Установка CefSharp

  • Установите CefSharp.Wpf через NuGet (я использую v1.25.7)
  • Это должно помещать соответствующие файлы в $(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef

Настройка сборки

  • Чтобы библиотеки DLL CefSharp могли копироваться в наши папки создания, щелкните правой кнопкой мыши на своем проекте, выберите "Свойства" → "События сборки" и введите в "Командная строка события после сборки" следующее:

    xcopy "$ (SolutionDir) пакеты \CefSharp.Wpf.1.25.7\cef *" "$ (TargetDir)" /s/y/i

  • Теперь необходимо скопировать все требуемые DLL из папки cef, а также файл devtools_resources.pak и папку locales и его содержимое. Я требую их в своем проекте, поскольку мне нужны инструменты для создания хрома.

  • Дважды проверьте ссылки на проект, содержащие CefSharp и CefSharp.Wpf. Это должно было заботиться NuGet.

Уход за файлами Runtime Visual С++ 2012

  • Я не хотел, чтобы пользователь загружал все файлы Runtime Visual С++ 2012 как часть развертывания, поэтому через Visual Studio добавьте папку Lib\Microsoft.VC110.CRT и добавьте 3 библиотеки DLL (msvcp110.dll, msvcr110.dll, vccorlib110.dll) из следующей папки на вашем компьютере в папку, которую вы только что создали в своем проекте:

    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\redist\x86\Microsoft.VC110.CRT

  • Выберите 3 DLL файла в Visual Studio, щелкните правой кнопкой мыши → свойства. Убедитесь, что для параметра "Действие сборки" установлено значение "Нет", а для "Копировать в выходной каталог" выбрано "Не копировать". Теперь вам нужно добавить еще одно событие post-build, чтобы убедиться, что они скопированы правильно (т.е. Скопированы в корневой каталог, чтобы они сидели рядом с DLL CEF и вашим exe проекта) для отладки.

  • Щелкните правой кнопкой мыши на своем проекте, выберите "Свойства" → "События сборки" и введите следующую команду в командной строке "Послестрочная сборка событий" сразу после вашей другой команды xcopy для CEF:

    xcopy "$ (ProjectDir) Lib\Microsoft.VC110.CRT *. *" "$ (TargetDir)" /s/y/i

В этот момент все должно строиться. Чтобы опубликовать приложение с помощью ClickOnce, мне нужно, чтобы он удалял все DLL-библиотеки CEF, а также обеспечивал наличие файлов/папок, необходимых для инструментов Chrome. Если вам не нужны инструменты dev или все библиотеки DLL, вы можете настроить их соответствующим образом.

Обеспечение развертывания файлов времени выполнения CEF и С++ с помощью ClickOnce

  • Щелкните правой кнопкой мыши свой проект в Visual Studio и выберите "выгрузить проект".
  • Щелкните правой кнопкой мыши и выберите, чтобы отредактировать файл csproj.
  • Перед закрывающим тегом </Project> добавьте этот

    <ItemGroup>
       <Content Include="$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef\**\*">
         <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
         <Visible>false</Visible>
      </Content>
    </ItemGroup>
    
    <ItemGroup>
       <Content Include="$(ProjectDir)Lib\Microsoft.VC110.CRT\**\*">
          <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
          <Visible>false</Visible>
      </Content>
    </ItemGroup>
    
  • Это добавит все из папки cef в проект и убедитесь, что двоичные файлы С++ скопированы в корень проекта при развертывании. В моем случае для CEF я использую синтаксис \**\* в конце Include и %(RecursiveDir), чтобы обеспечить копирование всех файлов, а также папку locales с сохранением содержимого и структуры. Установив <Visible>false</Visible>, вы не увидите элементы в проводнике решений.

Релакс

Теперь, если вы публикуете свое приложение, оно должно скопировать все необходимые файлы и папки.

Ответ 2

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

Добавьте DLL-библиотеки, не являющиеся библиотеками .NET, в решение в виде файлов:

Right click project > Add > Existing Item

Затем установите действие сборки для содержимого и "Скопировать в выходной каталог" на "Копировать всегда".

Таким образом, библиотеки будут включены в выходной каталог.

Ответ 3

Поскольку вы уже пытались вручную добавить подозрительную DLL, и это все еще не работает, следующая вещь, которую я бы сделал, это запустить fusion и посмотреть, на что она действительно жалуется, другими словами, что именно зависимость, которую нельзя загрузить, Вот хороший учебник о том, как выслеживать эти типы ошибок:

Обратно к основам: использование Fusion Log Viewer для отладки ошибок Obscure Loader

Ответ 4

Возможно, вы можете использовать его из https://github.com/Code52/DownmarkerWPF источников?

У них есть хотя бы рабочий установщик ClickOnce для своего приложения, встраивающего CefSharp. Я знаю, потому что так оно и было установлено на моей машине!

обновление только что увидело в комментариях, что это VC Redist, который, как вы говорите, отсутствует, Распространение библиотек времени выполнения Visual С++ (MSVCRT) кажется актуальным.

Кроме того, я, похоже, что-то смутно вспоминаю об этом для "причин VCRedist", вы не должны распространять отладочные версии своего приложения. Вы не можете просто переключиться с отладки на версию Release? С этим я думаю, что вы можете либо связать необходимые файлы VCRedist, как это предлагается в FAQ по CefSharp, либо добавить VCRedist в качестве предварительного условия в вашем установщике. DownmarkerWPF делает это со своей установкой установщика WIX, которую вы можете найти в филиале в своем репозитории GitHub. Что-то подобное AFAIK возможно с установкой VStudio в комплекте, если это то, что вы используете.

Ответ 5

Спасибо Барри ответить на это, это очень помогло мне. Я использую его ответ ниже, но обновляю его для работы с последним CEF, используя Visual Studio 2015.

ПРИМЕЧАНИЕ. Я только создаю/настраиваю платформу x86. Возможно, вам придется изменить или включить x64 в приведенные ниже команды копирования в соответствии с вашими потребностями.

Установка CefSharp

  • Установите CefSharp.Wpf через NuGet (я использую v51.0.0)

    Библиотека NuGet после установки

  • Это должно помещать соответствующие файлы в

    $(SolutionDir) пакеты \CefSharp.Wpf.51.0.0\CefSharp (CefSharp.Wpf) $(SolutionDir)\CefSharp.Common.51.0.0\CefSharp (CefSharp.Common) $(SolutionDir)\cef.redist.x86.3.2704.1432\CEF (Cef x86 redist) $(SolutionDir)\cef.redist.x64.3.2704.1432\CEF (Cef x64 redist)

Настройка сборки

  • Чтобы библиотеки DLL CefSharp копировались в наши папки сборки... Я не думаю, что это необходимо больше с более поздними версиями CefSharp. Я обнаружил, что мне не нужен какой-либо из материалов xcopy из командной строки "Post-build event", чтобы получить "Click-Once", чтобы отправить его. (И да, DevTools тоже работает!)

Уход за файлами Runtime Visual С++ 2012

  • (переключился на видеомагнитофон 2013) Я не хотел, чтобы пользователь загружал все Runtime файлы Visual С++ 2013 как часть развертывания, поэтому через Visual Studio добавьте папку lib\Microsoft.VC120. CRT и добавьте 3 библиотеки DLL (msvcp110.dll, msvcr110.dll, vccorlib110.dll) из следующей папки на вашем компьютере в папку, которую вы только что создали в своем проекте:

    C:\Windows\SysWOW64

    (Не видел их в C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist)

В этот момент все должно строиться. Чтобы опубликовать приложение с помощью ClickOnce, нам нужно, чтобы он удалял все библиотеки CEF DLL. Вы можете настроить это соответственно...

Обеспечение развертывания файлов времени выполнения CEF и С++ с помощью ClickOnce

  • Щелкните правой кнопкой мыши свой проект в Visual Studio и выберите "выгрузить проект".
  • Щелкните правой кнопкой мыши и выберите, чтобы отредактировать файл csproj.
  • Перед закрывающим тегом добавьте следующее:

    <!--  BEGIN: CUSTOM ITEM GROUP INCLUDES INTO THE PROJECT (SO CLICK-ONCE PUBLISHES THEM) -->
    <ItemGroup>
            <Content Include="$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\**\*" Exclude="$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\x86\**\*;$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\locales\**\*.pak">
                    <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
                    <Visible>false</Visible>
            </Content>
    </ItemGroup>
    <ItemGroup>
            <Content Include="$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\**\en-GB.*;$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\**\en-US.*">
                    <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
                    <Visible>false</Visible>
            </Content>
    </ItemGroup>
    <ItemGroup>
            <Content Include="$(SolutionDir)packages\cef.redist.x86.3.2704.1432\CEF\x86\**\*">
            <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
            <Visible>false</Visible>
            </Content>
    </ItemGroup>
    <ItemGroup>
            <Content Include="$(SolutionDir)packages\CefSharp.Common.51.0.0\CefSharp\x86\**\CefSharp.BrowserSubprocess.*">
                    <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
                    <Visible>false</Visible>
            </Content>
    </ItemGroup>
    <ItemGroup>
            <Content Include="$(ProjectDir)lib\Microsoft.VC120.CRT\**\*">
                    <Link>%(Filename)%(Extension)</Link>
                    <Visible>false</Visible>
            </Content>
    </ItemGroup>
    <!--  END: CUSTOM ITEM GROUP INCLUDES INTO THE PROJECT (SO CLICK-ONCE PUBLISHES THEM) -->
    
  • Это добавит все из папки cef в проект и убедитесь, что двоичные файлы С++ скопированы в корень проекта при развертывании. Установив false, вы не увидите элементы в проводнике решений.

  • ПОМНИТЕ: Я только создаю/настраиваю платформу x86. Возможно, вам потребуется изменить или включить x64 в приведенные ниже команды копирования в соответствии с вашими потребностями.

Опубликовать

Теперь, если вы публикуете свое приложение, оно должно скопировать все необходимые файлы и папки.


(ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ) Поддержка более ранних операционных систем ниже

Если вам нужно использовать CefSharp для более старых машин (XP и Vista), просто установите CefSharp.Wpf через NuGet, используя более старую версию v47.0.0, и измените свой таргетинг .NET на профиль клиента .NET 4.0.

Chromium завершила поддержку XP и Vista в апреле 2016 года, CefSharp версии 47 (или там abouts) все еще поддерживала его.

Еще одно примечание к проблеме и исправление для XP:

Существует проблема Chromium для развертывания XP. Ниже приведена статья, описывающая исправление, а затем шаги по развертыванию исправления для JBCB.

Здесь ссылка на статью: https://bitbucket.org/chromiumembedded/cef/issues/1787

... в нем вы увидите ссылку для загрузки "dbghelp.dll". Загрузите и извлеките.


ВЫ МОЖЕТЕ ПРИНИМАТЬ ПОСТ-УСТАНОВКУ ПОДХОДА, КАК НИЖЕ ИЛИ ВЫБИРАТЬ, ЧТОБЫ ВКЛЮЧАТЬ ДИСКУ С ДРУГИМИ ОПУБЛИКОВАННЫМИ ФАЙЛАМИ. Я ВЫБИРАЮ, ЧТОБЫ НЕ РАЗЛИЧИТЬ ДОПОЛНИТЕЛЬНУЮ DLL И ТОЛЬКО РАЗМЕЩЕНИЕ НА СТАНКАХ XP (МЫ ТОЛЬКО НЕСКОЛЬКО) ПРОЧИТАНО.


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

  • Установите браузер CefSharp на компьютере XP (через Click-Once)
  • Скопируйте файл "dbghelp.dll"
  • Вставьте его в локальный каталог установки на компьютере XP (в соответствии с инструкциями в предыдущей ссылке: вдоль файла "libcef.dll" ).

ПРИМЕЧАНИЕ. Для установок с однократной установкой будет находиться в подпапке в этом месте:

C:\Documents and Settings\<UserName>\Local Settings\Apps\2.0\<auto-gen ostificated ID>

Ответ 6

Внимательно прочитайте официальный список зависимостей CefSharp - их много! Вам нужно как-то поместить их в папку "ClickOnce bin".

Вот как я это решил:

  • Перед развертыванием установите последнюю версию Visual C++ Redistributable. на каждом ПК, на котором вы развертываете (используя групповую политику или просто вручную).
  • Начните с пустого тестового проекта.
  • Добавьте ссылки на CefSharp в CefSharp, CefSharp.Core и т.д.
  • Добавьте каждую зависимость в одну папку в каталоге проекта, чтобы сохранить их организованность (Files\CefSharp\).
  • Убедитесь, что все файлы настроены с помощью Build Action: Content и Copy to Output Dir: Copy always.
  • Создайте функцию Initalise_CefSharpFiles() для копирования файлов/папок в корневую папку bin (где их ищет CefSharp). Например, скопируйте из: Bin\Files\CefSharp\* в: Bin\*.
  • И, наконец, во время выполнения, вызывайте Initalise_CefSharpFiles() один раз после загрузки приложения и перед инициализацией настроек CefSharp.