Выполнение JavaScript на C# с CefSharp WPF вызывает ошибку
всякий раз, когда я пытаюсь выполнить JavaScript через C# с помощью CefSharp (стабильный 57.0), я получаю ошибку. Я просто пытаюсь выполнить функцию alert, Чтобы убедиться, что она работает, а затем протестировать ее с помощью моей собственной функции. Однако, кажется, я получаю ошибки, пытаясь это сделать.
public partial class WebBrowserWindow : Window
{
public WebBrowserWindow()
{
InitializeComponent();
webBrowser.MenuHandler = new ContextMenuHandler();
webBrowser.RequestHandler = new RequestHandler();
}
//Trying to execute this with either method gives me an error.
public void ExecuteJavaScript()
{
//webBrowser.GetMainFrame().ExecuteJavaScriptAsync("alert('test')");
//webBrowser.ExecuteScriptAsync("alert('test');");
}
}
Я пробовал оба способа выполнения скрипта.
первый:
webBrowser.GetMainFrame().ExecuteJavaScriptAsync("alert('test')");
дает мне это ошибка:
второй:
webBrowser.ExecuteScriptAsync("alert('test');");
дает мне эту ошибку:
моя цель-создать функцию C#, которая может выполнять функцию JavaScript в моем браузере CefSharp.
Я пробовал много ссылок / ссылок, и не было так много переполнения стека. Я тоже читал FAQ для CefSharp и не смог найти простых примеров, которые позволяют мне выполняйте JavaScript по желанию через C#.
кроме того, я проверил события, в которых загружается фрейм (он заканчивает загрузку) и выгружается (он не выгружается), и если webbrowser равен null (что не так), и сообщение от:
webBrowser.GetMainFrame().ExecuteJavaScriptAsync("alert('test')");
по-прежнему вызывает первую ошибку.
Я тестировал GetMainFrame (). Он всегда возвращает null. ВСЕГДА. Не имеет значения, как долго я жду, или какие условия я проверяю для.
важно
Я забыл добавить одну важную информацию, у меня есть 2 сборки в моем проекте. Оба они компилируются в отдельные исполняемые файлы:
помощником.исполняемый Главный.exe
main.exe имеет окно "CallUI", которое при нажатии кнопки выполняет метод, который я создал" ExecuteJavaScript ()", который находится внутри моего окна"BrowserWindow". Окно CallUI объявляется и инициализируется в Помощник.исполняемый.
поэтому в основном я пытаюсь использовать отдельную программу для открытия окна, нажмите кнопку, которая вызывает метод и выполняет javascript. Поэтому я думаю, что, поскольку это разные процессы, он говорит мне, что браузер равен нулю. Однако, когда я делаю все это в основном.exe он работает нормально. Есть обходной путь, который позволяет мне использовать отдельный процесс для создания окна с помощником.exe и выполнить Javascript из Main.exe?
2 ответов
до моего внимания дошло, что я обращался с проблемой неправильно.
моя проблема, на самом деле, не существует, если это всего лишь один процесс, удерживающий весь код вместе. Однако проблема заключалась в том, что в моем проекте был исполняемый файл, который пытался связаться с другим. На самом деле у меня никогда не было возможности помочь.exe, чтобы поговорить с моим главным.exe соответствующим образом.
из этого я узнал, что процессы пытались поговорить друг с другом без какого-либо общего доступа к адресу. Они живут в разных адресных пространствах, поэтому всякий раз мой помощник.exe попытался выполнить ту часть javascript, которая принадлежала Main.exe, он пытался выполнить сценарий в неинициализированной версии браузера, который принадлежал к его собственному адресному пространству, а не main.исполняемый.
Итак, как я решил эту проблему? Я должен был включить важную часть, которая позволила помощнику.exe процесс, чтобы поговорить с основным.процесс exe. Как я googled, как процессы могут разговаривать друг с другом, я узнал о MemoryMappedFiles. Поэтому я решил реализовать простой пример в своей программе, который позволяет Helper.exe для отправки сообщений в Main.исполняемый.
вот пример. Этот файл я создал под названием "MemoryMappedHandler.cs"
public class MemoryMappedHandler
{
MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("mmf1", 512);
MemoryMappedViewStream stream;
MemoryMappedViewAccessor accessor;
BinaryReader reader;
public static Message message = new Message();
public MemoryMappedHandler()
{
stream = mmf.CreateViewStream();
accessor = mmf.CreateViewAccessor();
reader = new BinaryReader(stream);
new Thread(() =>
{
while (stream.CanRead)
{
Thread.Sleep(500);
message.MyStringWithEvent = reader.ReadString();
accessor.Write(0, 0);
stream.Position = 0;
}
}).Start();
}
public static void PassMessage(string message)
{
try
{
using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("mmf1"))
{
using (MemoryMappedViewStream stream = mmf.CreateViewStream(0, 512))
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(message);
}
}
}
catch (FileNotFoundException)
{
MessageBox.Show("Cannot Send a Message. Please open Main.exe");
}
}
}
это скомпилировано в dll, которая является основной.exe и помощником.exe может использовать.
помощником.exe использует метод PassMessage () для отправки сообщения в сопоставленный с памятью файл с именем "mmf1". Главный.exe, который должен быть открыт в любое время, заботится о создании того файла, который может получать сообщения от помощника.исполняемый. Я отправляю это сообщение классу, который содержит это сообщение, и каждый раз, когда он его получает, он активирует событие.
вот как выглядит класс сообщений:
[Serializable]
public class Message
{
public event EventHandler HasMessage;
public string _myStringWithEvent;
public string MyStringWithEvent
{
get { return _myStringWithEvent; }
set
{
_myStringWithEvent = value;
if (value != null && value != String.Empty)
{
if (HasMessage != null)
HasMessage(this, EventArgs.Empty);
}
}
}
}
наконец, мне пришлось инициализировать сообщение в моем классе WebBrowserWindow следующим образом:
public partial class WebBrowserWindow : Window
{
public WebBrowserWindow()
{
InitializeComponent();
webBrowser.MenuHandler = new ContextMenuHandler();
webBrowser.RequestHandler = new RequestHandler();
MemoryMappedHandler.message.HasMessage += Message_HasMessage;
}
private void Message_HasMessage(object sender, EventArgs e)
{
ExecuteJavaScript(MemoryMappedHandler.message.MyStringWithEvent);
}
public void ExecuteJavaScript(string message)
{
//webBrowser.GetMainFrame().ExecuteJavaScriptAsync("alert('test')");
//webBrowser.ExecuteScriptAsync("alert('test');");
}
}
и теперь он позволяет мне выполнить javascript, который мне нужен, отправив сообщение из Помощник.exe к основному.исполняемый.
вы пробовали эту ссылку? Содержит фрагмент, который проверяет, инициализирован ли браузер первым.
private void OnIsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs args)
{
if(args.IsBrowserInitialized)
{
browser.ExecuteScriptAsync("alert('test');");
}
}