我正在尝试通过 SharePoint 计时器作业安排存储在 SharePoint 中的页面的 CefSharp 呈现。但是,OWSTIMER.exe 服务在调用 Cef.Initialize() 后几乎立即崩溃,几乎没有错误。
订阅类是:
internal class Subscriptions: IDisposable
{
internal Subscriptions()
{
db = // CreateConnection();
if (Cef.IsInitialized == false)
{
var settings = new CefSettings
{
CachePath = "cache",
BrowserSubprocessPath = "ProjectBin\\CefSharp.BrowserSubprocess.exe",
LogSeverity = LogSeverity.Default,
};
Cef.Initialize(settings);
}
}
internal void RunTodaysSubscriptions()
{
var subs = db.tt_ScheduledJobs.Where(sj => sj.Date <= DateTime.Today).Select(sj => sj.tt_Subscription).ToList();
foreach (var sub in subs)
{
ExecuteSubscription(sub);
SetNextSchedule(sub);
}
}
private void ExecuteSubscription(tt_Subscription subscription)
{
tt_JobHistory historyEntry = new tt_JobHistory();
historyEntry.SubscriptionKey = subscription.SubscriptionKey;
historyEntry.StartDate = DateTime.Now;
historyEntry.Status = "In Progress";
dfe.tt_JobHistory.Add(historyEntry);
dfe.SaveChanges();
string url = //path to file
using (SubscriptionExecution se = new SubscriptionExecution(
url,
subscription.SubscriptionKey,
subscription.Format))
{
//Completed represents either a response from the dashboard that the export either succeded
//or failed. If there is no response (i.e. a javascript error preventing the dashboard from executing
//an export, then we would hit the timeout of 5 minutes and shutdown this process.
if (SpinWait.SpinUntil(() => se.Completed == true, 120000) == true)
{
//Had a response from dashboard, could be a success or failure
if (se.ServerModel.Success == true) SuccessHistoryEntry(historyEntry);
else ErrorHistoryEntry(se.ServerModel.Message, historyEntry);
}
else
{
ErrorHistoryEntry("Process timed out generating subscription", historyEntry);
}
}
db.SaveChanges();
}
// ...
}
订阅执行是:
internal class SubscriptionExecution : IDisposable
{
// ...
internal SubscriptionExecution(string url, int subscriptionId, string fileType, string logLocation)
{
LogLocation = logLocation;
SubscriptionId = subscriptionId;
FileType = fileType;
Completed = false;
ServerModel = new ServerModel();
ServerModel.PropertyChanged += new PropertyChangedEventHandler(ServerModel_PropertyChanged);
browser = new ChromiumWebBrowser(url);
browser.RegisterJsObject("serverModel", ServerModel);
browser.LoadingStateChanged += LoadingStateChanged;
if (LogLocation != string.Empty) browser.ConsoleMessage += BrowserConsoleMessage;
}
private void ServerModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Success")
{
Completed = true;
}
}
// ...
}
有一个 loadingStateChange 函数可以在事件发生时注入一些修改 ServerModel.Success 字段的 javascript。
但是,我似乎无法做到这一点。除非在一种特定情况下,timerjob 到达该Cef.Initialize(settings)
部分,然后立即重新启动。不幸的是,在事件日志之外,找不到任何错误消息。
在 Windows 事件日志中, 表明 libcef.dll 中有错误
我已经为这个版本的 cefsharp (v57) 安装了 libcef.dll.pdb 符号。CefSharp 故障排除指南建议在这种情况下,应该有日志文件或错误转储。在包含可执行文件的文件夹中应该有一个文件“debug.log”,并且可能在 AppData\Local\CrashDumps 中有一个小型故障转储文件。
但是,由于这是一项 SharePoint 计时器作业,因此这些文件似乎没有出现。我确实在 15 hive bin (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\BIN) 中找到了一个 debug.log 文件;但是这个文件是空的。
我在任何地方都找不到 CrashDumps 文件夹;检查机器上的所有用户帐户,尤其是运行帐户和 SharePoint Timer Job 托管帐户。
我可以在不重新启动计时器作业的情况下运行代码的一种特定情况是在服务器重新启动后立即运行。重新启动服务器(暂时)解决了围绕这个问题的一些其他问题,所以我怀疑它可能是相关的。也就是说,我在收回和重新部署场解决方案时遇到了麻烦。这会引发几个不同的错误:
- 关于收回:<SERVER>:进程无法访问文件 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\BIN...\icudtl.dat',因为它正被另一个进程使用。
错误:删除此文件失败:C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\BIN...\icudtl.dat。 - 部署时:无法对打开了用户映射部分的文件执行请求的操作。
我试图使用 Process Explorer 查找其他进程正在使用 icudtl.dat,但我能找到的只是 chrome,它正在访问不同的副本。杀死所有 chrome 进程并再次尝试也没有解决问题。