15

尝试部署我创建的 C#/WPF 应用程序对第​​ 3 方 DLL 有一些引用时,我感到非常沮丧。我在项目中创建了一个名为 的文件夹lib,其中放置了所有这些 DLL。在 VS2012 中,我通过浏览到该文件夹​​并选择所有 DLL 添加了引用。 Copy Local设置true为所有人。构建和运行时一切都很好,但是当我选择发布并创建 OneClick 安装程序时,事情就不那么顺利了。在发布向导期间,我将其设置为从磁盘安装,并将其设置为从不检查更新。我拿那个文件夹,把它放在闪存驱动器上,把它插到另一台电脑上,运行安装程序,它会抛出一个异常。我相信我知道发生了什么,但我无法弄清楚如何打包它以便正确部署它。

我的 DLL 之一是为 C++ 项目设计的 DLL 的 C# 包装器。我们会说,ApplicationrequiresDLL1DLL1requires DLL2DLL2不能作为引用添加到项目中,因为它不是.NETDLL。 DLL1需要DLL2在同一个文件夹中才能拿起它。我正在使用包装Chromium Embedded Framework的CefSharp

我尝试将 CefSharp.dll 所需的 DLL 放在publish/Application Files目录中,但它不起作用。我注意到 VS2012 中的所有 DLL 都有一个.deploy扩展名,我什至去添加了那个扩展名,看看它是否正在扫描以获取它,但它也不起作用。这是我第一次为 Windows 应用程序进行开发和部署,我读过的 MSDN 上的所有教程或博客文章似乎都没有涵盖这种情况,而且我在部署管理器中看不到任何其他选项来处理这些问题案件类型。

如果有帮助,抛出的异常代码是:CLR20r3

当我捕获并显示异常时,我提供的所有信息基本上都是CefSharp.dll or one of it's dependencies cannot be loaded. 我之前得到DLL2的那个和DLL1.

在这种情况下,任何人都可以提供有关如何从 VS2012 进行部署的帮助吗?

提前致谢!

编辑:信息更新

我试图在没有安装 Visual Studio 的情况下将调试版本推送到测试机器。在为CefSharp或任何其他 C++ Runtime构建时DLL,它将查找DLL通常名称相同但在末尾添加字母“d”的所有 Debug 版本。如下所述,C++ 运行时的调试版本不可再分发。并不是说您不能手动将它们添加DLLs到您的项目中并将它们设置为Copy Always,但这是一种黑客工作。我从头开始了一个新项目,添加了所有发布版本的 DLL,构建,一切都很好。

4

6 回答 6

23

今天早上我一直在努力解决这个问题,最终找到了解决方案。看来您已经知道 CefSharp 工作需要哪些 DLL 等,但我想我会通过这个,以防其他人遇到同样的问题。我有一个 C# WPF 应用程序,我使用 CefSharp 作为 Web 视图。我正在使用 CefSharp v1,因为我需要他们提供的 JavaScript -> C# 桥接器,而该桥接器尚未在 v3 中实现。这是我在设置项目时所经历的粗略步骤(我使用的是 VS2013,但这可能适用于 VS2012)。

安装 CefSharp

  • 通过 NuGet 安装 CefSharp.Wpf(我使用的是 v1.25.7)
  • 那应该把相关文件放在$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef

配置构建

  • 要将 CefSharp DLL 复制到我们的构建文件夹,请右键单击您的项目,选择 Properties -> Build Events 并在“Post-build event command line”中输入以下内容:

    xcopy "$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef*" "$(TargetDir)" /s /y /i

  • 现在应该从 cef 文件夹以及devtools_resources.pak文件和locales文件夹及其内容复制所有必需的 DLL。我在我的项目中需要它们,因为我需要 chromium 开发工具。

  • 仔细检查您的项目引用包含CefSharpCefSharp.Wpf。这应该由 NuGet 处理。

处理 Visual C++ 2012 运行时文件

  • 我不希望用户必须下载整个 Visual C++ 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

  • 在Visual Studio中选择3个DLL文件,右键->属性。确保构建操作设置为“无”并且复制到输出目录设置为“不复制”。现在您需要添加另一个构建后事件以确保正确复制这些事件(即复制到根目录,以便它们与 CEF dll 和您的项目 exe 并排放置)以进行调试。

  • 右键单击您的项目,选择 Properties -> Build Events,然后在 CEF 的其他 xcopy 命令之后的“构建后事件命令行”中输入以下内容:

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

在这一点上,一切都应该建立。要使用 ClickOnce 发布应用程序,我需要它来推出所有 CEF DLL,并确保存在 chromium 开发工具所需的文件/文件夹。如果您不需要开发工具或所有 DLL,那么您可以相应地进行调整。

确保使用 ClickOnce 部署 CEF 和 C++ 运行时文件

  • 在 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 文件夹中的所有内容添加到项目中,并确保 C++ 二进制文件在部署时复制到项目的根目录。对于 CEF,我\**\*在 Include 末尾使用语法,并%(RecursiveDir)确保复制所有文件以及locales保留其内容和结构的文件夹。设置后<Visible>false</Visible>,您将看不到解决方案资源管理器中的项目。

放松

现在,如果您发布您的应用程序,它应该会复制所有必需的文件和文件夹。

于 2014-06-18T14:08:40.813 回答
1

也许您可以从https://github.com/Code52/DownmarkerWPF来源中解决?

他们至少有一个可运行的ClickOnce 安装程序,用于嵌入 CefSharp 的应用程序。我知道,因为它就是这样安装在我的机器上的!

更新刚刚在评论中看到您说您缺少的是 VC Redist,然后分发 Visual C++ 运行时库 (MSVCRT)似乎相关。

此外,由于“VCRedist 原因”,我似乎还模糊地记得一些事情,您不应该分发应用程序的调试版本。你不能从调试版本切换到发布版本吗?有了这个,我认为您可以按照 CefSharp FAQ 中的建议捆绑所需的 VCRedist 文件,或者在安装程序中添加 VCRedist 作为先决条件。DownmarkerWPF 使用他们的 WIX 安装程序设置,您可以在他们的 GitHub 存储库中的一个分支上找到它。如果您使用的是 VStudio 捆绑安装程序,则可以使用类似的 AFAIK。

于 2014-04-04T13:47:22.477 回答
1

你可以试试这个,它为我解决了一个类似的问题:

将不是 .NET 库的 DLL 作为文件添加到解决方案中:

Right click project > Add > Existing Item

然后将他们的构建操作设置为内容并将“复制到输出目录”设置为“始终复制”。

这样库将包含在输出目录中。

于 2014-04-03T16:06:47.430 回答
1

由于您已经尝试手动添加可疑的 dll,但它仍然无法正常工作,接下来我要做的是运行 fusion 并查看它真正在抱怨什么,换句话说,无法加载的依赖项到底是什么。这是关于如何查找这些类型的错误的一个很好的教程:

回归基础:使用 Fusion Log Viewer 调试晦涩的加载程序错误

于 2014-04-03T16:54:56.423 回答
1

感谢巴里对此的回答,这对我帮助很大。我在下面使用他的答案,但使用 Visual Studio 2015 更新它以适用于最新的 CEF。

注意:我只构建/定位 x86 平台。您可能需要在下面的复制命令中更改或包含 x64 以满足您的需要。

安装 CefSharp

  • 通过 NuGet 安装 CefSharp.Wpf(我使用的是 v51.0.0)

    安装后的 NuGet 库

  • 那应该把相关文件放在

    $(SolutionDir)packages\CefSharp.Wpf.51.0.0\CefSharp (CefSharp.Wpf) $(SolutionDir)packages\CefSharp.Common.51.0.0\CefSharp (CefSharp.Common) $(SolutionDir)packages\cef.redist。 x86.3.2704.1432\CEF(Cef x86 再版)$(SolutionDir)packages\cef.redist.x64.3.2704.1432\CEF(Cef x64 再版)

配置构建

  • 为了让 CefSharp DLL 复制到我们的构建文件夹中......我认为对于 CefSharp 的更高版本不再需要这样做。我发现我不需要任何“构建后事件命令行”xcopy 东西来让 Click-Once 将其发送出去。(是的,DevTools 也可以!)

处理 Visual C++ 2012 运行时文件

  • (切换到 VCR 2013)我不希望用户必须下载整个 Visual C++ 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。您可以相应地调整它...

确保使用 ClickOnce 部署 CEF 和 C++ 运行时文件

  • 在 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 文件夹中的所有内容添加到项目中,并确保 C++ 二进制文件在部署时复制到项目的根目录。设置为 false 您将看不到解决方案资源管理器中的项目。

  • 记住:我只是在构建/定位 x86 平台。您可能需要在下面的复制命令中更改或包含 x64 以满足您的需要。

发布

现在,如果您发布您的应用程序,它应该会复制所有必需的文件和文件夹。


(额外信息)支持下面的旧操作系统信息

如果您需要在较旧的机器(XP 和 Vista)上使用 CefSharp,只需使用较旧的 v47.0.0 版本通过 NuGet 安装 CefSharp.Wpf,并将您的 .NET 目标更改为 .NET 4.0 客户端配置文件。

Chromium 在 2016 年 4 月结束了对 XP 和 Vista 的支持,CefSharp 版本 47(或大约版本)仍然支持它。

关于 XP 的问题和修复的另一个说明:

XP 部署存在 Chromium 问题。以下是描述修复的文章,以及为 JBCB 部署修复的步骤。

这是文章的链接: https ://bitbucket.org/chromiumembedded/cef/issues/1787

...在其中您将看到下载“dbghelp.dll”的参考。下载并解压。


您可以采用如下所示的安装后方法,或选择将 DLL 与您发布的其他文件一起包含在内。我选择不部署额外的 DLL,只在 XP 机器上手动部署(我们只有少数)。


采取这些步骤来修复 XP 机器上的部署:

  1. 在 XP 机器上安装 CefSharp 浏览器(通过 Click-Once)
  2. 复制“dbghelp.dll”
  3. 将其粘贴到 XP 机器上的本地安装目录中(按照上一个链接中的说明:在“libcef.dll”文件旁边)。

注意:对于单击一次安装,将位于此位置下的子文件夹中:

C:\Documents and Settings\<UserName>\Local Settings\Apps\2.0\<auto-gen ostificated ID>
于 2016-10-29T15:31:16.970 回答
0

仔细阅读CefSharp 依赖项的官方列表- 其中有很多!您需要以某种方式将它们全部放入 ClickOnce bin 文件夹中。

这是我解决它的方法:

  • 在部署之前,安装最新版本的Visual C++ Redistributable。在您要部署到的每台 PC 上(使用组策略或仅手动)。
  • 从一个空白测试项目开始。
  • 将项目引用添加到CefSharpCefSharp.Core等。
  • 将每个依赖项添加到项目目录中的单个文件夹中以保持它们的组织性 ( Files\CefSharp\)。
  • 确保所有文件都配置有Build Action: Content, 和Copy to Output Dir: Copy always.
  • 创建一个函数Initalise_CefSharpFiles()将文件/文件夹复制到 bin 根文件夹(CefSharp 查找它们的位置)。例如,从:复制Bin\Files\CefSharp\*到:Bin\*
  • 最后在运行时,Initalise_CefSharpFiles()在应用加载后和初始化 CefSharp 的设置之前调用一次。
于 2018-12-12T03:56:29.990 回答