我一直非常沮丧地尝试部署我创建的C#/ WPF应用程序,该应用程序有一些对第三方DLL的引用。我在项目中创建了一个名为lib
的文件夹,在那里我放置了所有这些DLL。在VS2012中,我通过浏览到该文件夹并选择所有DLL来添加引用。对于所有人,Copy Local
设置为true
。我构建和运行时一切都很好,但是当我选择发布并创建OneClick安装程序时,事情就不那么顺利了。在发布向导期间,我将其设置为从磁盘安装,并将其设置为从不检查更新。我拿这个文件夹,把它放在闪存驱动器上,插入另一台PC,运行安装程序,然后抛出异常。我相信我知道发生了什么,但我无法弄清楚如何打包它以便正确部署它。
我的一个DLL是为C ++项目设计的DLL的C#包装器。我们会说,Application
需要DLL1
而DLL1
需要DLL2
。 DLL2
无法作为项目中的引用添加,因为它不是.NET
DLL。 DLL1
要求DLL2
位于同一文件夹中才能获取它。我正在使用CefSharp封装Chromium Embedded Framework。
我已尝试将所需的CefSharp.dll DLL放在publish/Application Files
目录中,但它不起作用。我注意到VS2012上的所有DLL都有一个.deploy
扩展名,我甚至去添加扩展名以查看它是否正在扫描以获取它,但它也没有用。这是我第一次为Windows应用程序进行开发和部署,我读过的所有关于MSDN或博客文章的教程似乎都没有涵盖这种情况,我在Deployment Manager中看不到任何其他选项来处理这些案件类型。
如果有帮助,抛出的异常代码为:CLR20r3
当我抓住并显示Exception时,我提供的所有信息基本上都是CefSharp.dll or one of it's dependencies cannot be loaded
。我DLL2
与DLL1
不在同一文件夹中时所得到的。
任何人都可以提供有关如何从VS2012部署此类情况的帮助吗?
提前致谢!
修改:信息更新
我试图将调试版本推送到没有安装Visual Studio的测试机器。在构建CefSharp
或任何其他C ++运行时DLL
时,它将查找DLL
的所有调试版本,这些版本通常具有相同的名称,但添加了字母“d”到最后。如下所述,C ++ Runtime的Debug版本不可再发行。并不是说您无法手动将DLLs
添加到项目中并将其设置为Copy Always
,但这是一种黑客工作。我从头开始了一个新项目,添加了DLL的所有Release版本,并且一切都很好。
答案 0 :(得分:21)
我今天早上一直在试图解决这个问题,并最终找到了解决办法。看来你已经知道CEFSharp需要哪些DLL等工作但我想我会遇到这个以防其他人遇到同样的问题。我有一个C#WPF应用程序,我使用CEFSharp作为Web视图。我使用CEFSharp v1因为我需要JavaScript - >它们提供的C#桥在v3中尚未实现。以下是我在设置项目时所经历的粗略步骤(我使用的是VS2013,但这可能适用于VS2012)。
$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef
要将CefSharp DLL复制到我们的构建文件夹,请右键单击您的项目,选择Properties - >构建事件并在"构建后事件命令行":
中输入以下内容xcopy" $(SolutionDir)packages \ CefSharp.Wpf.1.25.7 \ cef *" " $(TARGETDIR)" / s / y / i
现在应该从cef文件夹以及devtools_resources.pak
文件和locales
文件夹及其内容中复制所有必需的DLL。我需要他们在我的项目中,因为我需要chrome dev工具。
CefSharp
和CefSharp.Wpf
。应该由NuGet负责。我不希望用户必须下载整个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文件,右键单击 - >属性。确保将Build Action设置为" None"和复制到输出目录设置为"不复制"。现在你需要添加另一个post-build事件以确保它们被正确复制(即复制到root,以便它们与CEF dll和你的项目exe一起放置)进行调试。
右键单击您的项目,选择属性 - >构建事件并在"构建后事件命令行中输入以下内容"紧跟CEF的其他xcopy命令之后:
xcopy" $(ProjectDir)Lib \ Microsoft.VC110.CRT *。*" " $(TARGETDIR)" / s / y / i
此时,一切都应该建立起来。要使用ClickOnce发布应用程序,我需要它来推出所有CEF DLL以及确保chrome dev工具所需的文件/文件夹。如果您不需要开发工具或所有DLL,那么您可以相应调整它。
在结束</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>
后,您将无法查看解决方案资源管理器中的项目。
现在,如果你发布你的应用程序,它应该复制所有必需的文件和文件夹。
答案 1 :(得分:1)
你可以尝试这个解决了类似的问题:
将不是.NET库的DLL作为文件添加到解决方案中:
Right click project > Add > Existing Item
然后将构建操作设置为Content,将“Copy to output directory”设置为“Copy Always”。
这样,库将包含在输出目录中。
答案 2 :(得分:1)
既然你已经尝试过手动添加可疑dll并且它仍然无效,我接下来要做的就是运行fusion并查看它真正抱怨的内容,换句话说,无法加载的依赖是什么。这是一个关于如何寻找这些类型的错误的好教程:
Back to Basics: Using Fusion Log Viewer to Debug Obscure Loader Errors
答案 3 :(得分:1)
也许你可以从https://github.com/Code52/DownmarkerWPF来源解决这个问题?
他们的应用嵌入CefSharp至少有一个工作ClickOnce installer。我知道,因为这是我在我的机器上安装的方式!
更新只是在评论中看到你说你失踪的VC Redist然后Distributing the Visual C++ Runtime Libraries (MSVCRT)似乎相关。
此外,我似乎还记得一些含糊不清的东西,因为VCRedist的原因&#34;您不应该分发应用程序的调试版本。你不能只是从Debug转换到Release版本吗?有了这个,我想你可以按照CefSharp FAQ中的建议捆绑所需的VCRedist文件,或者在你的安装程序中添加VCRedist作为先决条件。 DownmarkerWPF使用他们的WIX安装程序设置,您可以在他们的GitHub仓库中的分支上找到它。如果使用VStudio捆绑式安装程序,AFAIK可能会有类似的东西。
答案 4 :(得分:1)
感谢Barrie对此的回答,这对我帮助很大。我正在使用下面的答案,但是使用Visual Studio 2015将其更新为最新的CEF。
注意:我只构建/定位x86平台。您可能需要在下面的复制命令中更改或包含x64以满足您的需要。
安装CefSharp
通过NuGet安装CefSharp.Wpf(我使用的是v51.0.0)
那应该将相关文件放在
中$(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 redist) $(SolutionDir)packages \ cef.redist.x64.3.2704.1432 \ CEF(Cef x64 redist)
配置构建
处理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 ++运行时文件在结束标记之前添加以下内容:
<!-- 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后,您将无法在解决方案资源管理器中看到这些项目。
发布强>
现在,如果您发布应用程序,它应该复制所有必需的文件和文件夹。
(EXTRA INFO)支持下面的旧操作系统信息
如果您需要将CefSharp用于旧机器(XP和Vista),请简单地说 使用旧的v47.0.0版本通过NuGet安装CefSharp.Wpf,并将.NET目标更改为.NET 4.0 Client Profile。
Chromium在2016年4月结束了对XP和Vista的支持,CefSharp版本47(或其他版本)仍然支持它。
关于问题和修复XP的另一个注意事项:
XP部署存在Chromium问题。下面是描述修复程序的文章,后面是为JBCB部署修补程序的步骤。
这是文章的链接: https://bitbucket.org/chromiumembedded/cef/issues/1787
...在其中你会看到一个下载“dbghelp.dll”的引用。下载并解压缩。
您可以采取下面的安装后方法,或选择与您的其他已发布文件一起包含DLL。我正在选择不部署额外的DLL并且只能手动部署XP机器(我们只有很少)。
采取以下步骤修复XP机器上的部署:
注意:对于一次性安装,将位于此位置下的子文件夹中:
C:\Documents and Settings\<UserName>\Local Settings\Apps\2.0\<auto-gen ostificated ID>
答案 5 :(得分:0)
请仔细阅读CefSharp dependencies的官方列表-其中很多!您需要以某种方式将它们全部放入ClickOnce bin文件夹中。
这是我解决的方法:
CefSharp
,CefSharp.Core
等Files\CefSharp\
)。Build Action: Content
和Copy to Output Dir: Copy always
。Initalise_CefSharpFiles()
将文件/文件夹复制到bin根文件夹(CefSharp在其中寻找它们)。例如,从以下位置复制:Bin\Files\CefSharp\*
到:Bin\*
。Initalise_CefSharpFiles()
。