1

LinqPad是我的 goto REPL,我对它的处理并不多。

但是,我一辈子都无法让CefSharp(特别是 OffScreen)运行。

我经常遇到以下任何一个错误

无法加载文件或程序集“CefSharp.Core.Runtime,Version=95.7.141.0,Culture=neutral,PublicKeyToken=40c4b6fc221f4138”或其依赖项之一。该系统找不到指定的文件。

BadImageFormatException:无法加载文件或程序集“CefSharp.Core.Runtime,版本=95.7.141.0,文化=中性,PublicKeyToken=40c4b6fc221f4138”。试图加载格式不正确的程序。

我努力了

  • LP5/6 32 和 64 位
  • 通过 nuget 添加 Cefsharp
  • 从文件系统手动引用 .dll
  • 引用 x86 或 x64 .dll
  • 将 .dll 复制到程序集搜索路径中
  • 将 nuget 路径添加到环境路径

以及上述的每一种组合。

我不了解 Visual Studio 与 nuget 包一起使用的程序集解析过程,但无论它做什么,我都想至少在 Linqpad 中进行模拟,这样我就可以在测试简单的东西时避免 VS 仪式。

我认为手动引用正确的 .dll 并可能在某处设置路径就足够了,但我的想法=> EOF。

CefSharp 可以在 VS/MSBuild 之外运行吗?

4

2 回答 2

0

由于 LinqPad 正在使用影子复制,它不起作用。这是一个让你的问题消失的技巧(剧透警告:不是真的,请继续阅读):

对于 LinqPad v5

  1. 将所有CefSharp库复制到一个单独的文件夹(不要忘记cef.redist)。
  2. 在 LinqPad 首选项对话框(高级/执行)中,设置Do not shadow assembly referencesTrue,重新启动 LinqPad。
  3. 在 LinqPad 查询中编写代码。
  4. CefSharp从您在步骤 1 中设置的文件夹中引用库。
  5. 运行查询。

对于以前的 LinqPad(早于 v5)

  1. 在 LinqPad 查询中编写代码。
  2. 参考CefSharp库,因此您可以从问题中获得例外
  3. 找到一个 LinqPad 工作目录(通常类似于C:\Users\<user>\AppData\Local\Temp\LINQPad5\_yyigmhzg)。
  4. 将所有CefSharp库复制到此文件夹(不要忘记cef.redist)。
  5. 在 LinqPad 中,单击Ctrl + Shift + F5; 这将重置查询状态。
  6. 重新运行查询。

现在应该加载所有引用的库。但在那之后你可能会面临更多的问题。

我无法让CefSharp.MinimalExample工作。LinqPad 一直在为我崩溃,并带有神秘的消息Query ended because an uncatchable exception was thrown和故障转储。

虽然我不确定您是否会让 CefSharp 在 LinqPad 下按预期工作,但也许这可以让您走得更远。

于 2021-11-15T01:14:43.283 回答
0

从@Sasha 的帖子和@amaitland关于' 不仅仅是不正确的架构的注释中找到了答案。BadImageFormatException

以下全部参考LP6CefSharp.Offscreen.NetCore。我还没有将努力推进到LP5,但过程应该是相似的。

经过反复试验,我缩小了所有必要的依赖项,并找出了CefSharp不能在LinqPad中运行的原因。

以下是使其运行的步骤 -

  1. 像往常一样添加CefSharp.Offscreen.NetCore包进行查询
  2. 启用将所有 NuGet 程序集复制到单个本地文件夹(F4-> 高级)
  3. 在查询中添加OnInit()queryPath代码如下
  4. 确保BrowserSubprocessPath在初始化 Cef 之前已设置

这是代码。

async Task Main()
{
    var are = new AutoResetEvent(false);//my technique for waiting for the browser
    var sett = new CefSettings();
    sett.BrowserSubprocessPath = this.queryPath + @"\CefSharp.BrowserSubprocess.exe";   //CefSharp will complain it cant find it
    if (!Cef.IsInitialized) 
        Cef.Initialize(sett);
    var browser = new ChromiumWebBrowser("http://www.google.com");
    browser.LoadingStateChanged += (sender, args) => { if (!args.IsLoading) are.Set(); };
    are.WaitOne();
    await browser.WaitForInitialLoadAsync();
    var html = await browser.GetBrowser().MainFrame.GetSourceAsync();
    html.Dump("winner winner chicken dinner");
}

//this is the location of the queries shaddow folder
string queryPath = Path.GetDirectoryName(typeof(CefSettings).Assembly.Location);

void OnInit() // Executes when the query process first loads
{
    if (!Directory.Exists(queryPath + @"\locales")) //subdirectory of cef.redist
    {
        var nugetPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
        var sources = new[] {
            /*paths here are hardcoded version dependant. Can get cefsharp.common.netcore version 
            from Util.CurrentQuery.NuGetReferences, but cef.redist not available via that method. */
            @"cef.redist.x64\95.7.14\CEF", //contans all the Cef dependencies needed
            @"cefsharp.common.netcore\95.7.141\runtimes\win-x64\lib\netcoreapp3.1", //mainly for ijwhost.dll
            @"cefsharp.common.netcore\95.7.141\runtimes\win-x64\native"}; //contains BrowserSubprocess & friends
        var dst = new DirectoryInfo(queryPath);
        foreach (var path in sources)
        {
            var src = new DirectoryInfo($@"{nugetPath}\.nuget\packages\{path}");
            CopyFilesRecursively(src, dst);
        }
    }
}

//curtesy of https://stackoverflow.com/a/58779/2738249 with slight mod
public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)
{
    foreach (DirectoryInfo dir in source.GetDirectories())
        CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
    foreach (FileInfo file in source.GetFiles())
    {
        var dst = Path.Combine(target.FullName, file.Name);
        if (!File.Exists(dst))
            file.CopyTo(dst);
    }
}

感兴趣的人的原因 -

CefSharp 需要每个依赖项都位于同一目录中,以便它们可以在运行时解析,但 Linqpad 仅从 NuGet 包中复制几个关键 dll。没有任何cef.redist文件,ijwhost.dllBrowserSubprocess.exe等。遇到。依赖项分散在 NuGet 包之间,尝试直接从 .nuget 缓存中解析它们是行不通的。所以所有这些都需要手动引入到正在运行的查询影子路径中。

我最初确实将所有文件复制到Assembly.GetExecutingAssembly().Location路径中,但是这种方法需要将程序集目录添加到“路径”环境变量中。在内部,Linqpad 似乎设置了影子路径,因此将依赖项复制到影子文件夹可以跳过设置环境变量的需要。

于 2021-11-17T00:47:40.747 回答