CefSharp.offscreen 在 LinqPad 中
CefSharp.offscreen in LinqPad
LinqPad 是我的 goto REPL,没有太多我无法处理的东西。
但是我一辈子都做不到 CefSharp(特别是 OffScreen)到 运行。
我经常遇到以下任一错误
Could not load file or assembly 'CefSharp.Core.Runtime, Version=95.7.141.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138' or one of its dependencies. The system cannot find the file specified.
BadImageFormatException: Could not load file or assembly 'CefSharp.Core.Runtime, Version=95.7.141.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138'. An attempt was made to load a program with an incorrect format.
我试过了
- LP5/6 32 位和 64 位
- 通过 nuget 添加 Cefsharp
- 从文件系统手动引用 .dll
- 引用 x86 或 x64 .dll 的
- 正在将 .dll 复制到程序集搜索路径
- 将 nuget 路径添加到环境路径
上面的每一个组合看起来都是什么。
我不明白 Visual Studio 与 nuget 包一起使用的程序集解析过程,但无论它做什么,我都想至少在 Linqpad 中进行模拟,这样我就可以在测试一些简单的东西时避免 VS 仪式.
我认为手动引用正确的 .dll 并可能在某处设置路径应该就足够了,但我的想法=>EOF。
CefSharp 可以 运行 在 VS / MSBuild 之外吗?
由于 LinqPad 使用的卷影复制,它不起作用。这是一个让你的问题消失的技巧(剧透警报:不是真的,请继续阅读):
对于 LinqPad v5
- 将所有
CefSharp
个库复制到一个单独的文件夹(不要忘记 cef.redist
)。
- 在 LinqPad 首选项对话框 (Advanced/Execution) 中,将
Do not shadow assembly references
设置为 True
,重新启动 LinqPad。
- 在 LinqPad 查询中编写代码。
- 从您在步骤 1 中设置的文件夹中引用
CefSharp
个库。
- 运行查询。
对于以前的 LinqPad(早于 v5)
- 在 LinqPad 查询中编写代码。
- 参考
CefSharp
个库,所以你的问题得到了例外
- 找到一个 LinqPad 工作目录(通常类似于
C:\Users\<user>\AppData\Local\Temp\LINQPad5\_yyigmhzg
)。
- 将所有
CefSharp
个库复制到此文件夹(不要忘记 cef.redist
)。
- 在LinqPad中,点击
Ctrl + Shift + F5
;这将重置查询状态。
- 重新运行查询。
现在应该加载所有引用的库。但是之后你可能会遇到更多的问题。
我无法让 CefSharp.MinimalExample 工作。 LinqPad 不断为我崩溃并显示神秘消息 Query ended because an uncatchable exception was thrown
和故障转储。
虽然我不确定您是否会让 CefSharp 在 LinqPad 下按预期工作,也许这可以让您更进一步。
从@Sasha 的post 和@amaitland 的note 中找到关于 BadImageFormatException
不仅仅是错误架构的答案。
以下均参考LP6 and CefSharp.Offscreen.NetCore. I have not pushed the efforts into LP5,但过程应该类似。
经过反复试验,我缩小了所有必要的依赖项范围,并找出了 CefSharp would not run in LinqPad.
的原因
以下是制作步骤运行 -
- 正常添加CefSharp.Offscreen.NetCore包查询
- 启用将所有 NuGet 程序集复制到一个本地文件夹中(F4->高级)
- 将下面的
OnInit()
和 queryPath
代码添加到查询中
- 确保在初始化 Cef
之前设置 BrowserSubprocessPath
这是代码。
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.7.14\CEF", //contans all the Cef dependencies needed
@"cefsharp.common.netcore.7.141\runtimes\win-x64\lib\netcoreapp3.1", //mainly for ijwhost.dll
@"cefsharp.common.netcore.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 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
文件中的 None,ijwhost.dll
或 BrowserSubprocess.exe
等。遇到。依赖项分散在 NuGet 包之间,尝试直接从 .nuget 缓存中解析它们是行不通的。所以这些都需要手动引入到运行ning query shadow path中。
我最初确实将所有文件复制到 Assembly.GetExecutingAssembly().Location
路径中,但这种方法需要将程序集目录添加到“路径”环境变量中。
Linqpad 内部似乎设置了 shadow 路径,所以将依赖项复制到 shadow 文件夹就可以跳过设置环境变量的需要。
LinqPad 是我的 goto REPL,没有太多我无法处理的东西。
但是我一辈子都做不到 CefSharp(特别是 OffScreen)到 运行。
我经常遇到以下任一错误
Could not load file or assembly 'CefSharp.Core.Runtime, Version=95.7.141.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138' or one of its dependencies. The system cannot find the file specified.
BadImageFormatException: Could not load file or assembly 'CefSharp.Core.Runtime, Version=95.7.141.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138'. An attempt was made to load a program with an incorrect format.
我试过了
- LP5/6 32 位和 64 位
- 通过 nuget 添加 Cefsharp
- 从文件系统手动引用 .dll
- 引用 x86 或 x64 .dll 的
- 正在将 .dll 复制到程序集搜索路径
- 将 nuget 路径添加到环境路径
上面的每一个组合看起来都是什么。
我不明白 Visual Studio 与 nuget 包一起使用的程序集解析过程,但无论它做什么,我都想至少在 Linqpad 中进行模拟,这样我就可以在测试一些简单的东西时避免 VS 仪式.
我认为手动引用正确的 .dll 并可能在某处设置路径应该就足够了,但我的想法=>EOF。
CefSharp 可以 运行 在 VS / MSBuild 之外吗?
由于 LinqPad 使用的卷影复制,它不起作用。这是一个让你的问题消失的技巧(剧透警报:不是真的,请继续阅读):
对于 LinqPad v5
- 将所有
CefSharp
个库复制到一个单独的文件夹(不要忘记cef.redist
)。 - 在 LinqPad 首选项对话框 (Advanced/Execution) 中,将
Do not shadow assembly references
设置为True
,重新启动 LinqPad。 - 在 LinqPad 查询中编写代码。
- 从您在步骤 1 中设置的文件夹中引用
CefSharp
个库。 - 运行查询。
对于以前的 LinqPad(早于 v5)
- 在 LinqPad 查询中编写代码。
- 参考
CefSharp
个库,所以你的问题得到了例外 - 找到一个 LinqPad 工作目录(通常类似于
C:\Users\<user>\AppData\Local\Temp\LINQPad5\_yyigmhzg
)。 - 将所有
CefSharp
个库复制到此文件夹(不要忘记cef.redist
)。 - 在LinqPad中,点击
Ctrl + Shift + F5
;这将重置查询状态。 - 重新运行查询。
现在应该加载所有引用的库。但是之后你可能会遇到更多的问题。
我无法让 CefSharp.MinimalExample 工作。 LinqPad 不断为我崩溃并显示神秘消息 Query ended because an uncatchable exception was thrown
和故障转储。
虽然我不确定您是否会让 CefSharp 在 LinqPad 下按预期工作,也许这可以让您更进一步。
从@Sasha 的post 和@amaitland 的note 中找到关于 BadImageFormatException
不仅仅是错误架构的答案。
以下均参考LP6 and CefSharp.Offscreen.NetCore. I have not pushed the efforts into LP5,但过程应该类似。
经过反复试验,我缩小了所有必要的依赖项范围,并找出了 CefSharp would not run in LinqPad.
的原因以下是制作步骤运行 -
- 正常添加CefSharp.Offscreen.NetCore包查询
- 启用将所有 NuGet 程序集复制到一个本地文件夹中(F4->高级)
- 将下面的
OnInit()
和queryPath
代码添加到查询中 - 确保在初始化 Cef 之前设置
BrowserSubprocessPath
这是代码。
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.7.14\CEF", //contans all the Cef dependencies needed
@"cefsharp.common.netcore.7.141\runtimes\win-x64\lib\netcoreapp3.1", //mainly for ijwhost.dll
@"cefsharp.common.netcore.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 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
文件中的 None,ijwhost.dll
或 BrowserSubprocess.exe
等。遇到。依赖项分散在 NuGet 包之间,尝试直接从 .nuget 缓存中解析它们是行不通的。所以这些都需要手动引入到运行ning query shadow path中。
我最初确实将所有文件复制到 Assembly.GetExecutingAssembly().Location
路径中,但这种方法需要将程序集目录添加到“路径”环境变量中。
Linqpad 内部似乎设置了 shadow 路径,所以将依赖项复制到 shadow 文件夹就可以跳过设置环境变量的需要。