前提・実現したいこと
C#で外部から読み込んだJava Scriptで処理をしようとしたのですが、
Windowsアプリケーションでは動くものが、コンソールアプリケーションでは動きません。
Windowsアプリケーションと同じ動作をさせるためには、何が必要ですか。
どこに問題がありますか。
追記
私が最終的にしたいことはWeb BrowserでJava Scriptを処理させ、C#で結果を受け取ることです。フォームを表示せずにWeb Browserを通じてJava Scriptとやりとりをしたいのです。
発生している問題・エラーメッセージ
WindowsアプリケーションではHello, world!
と表示されるが、
コンソールアプリケーションではnull
になる。
追記
Zuishinさんの指摘により、ソースコードが比較できるように変更したところ、
Windowsアプリケーションでも動作が怪しくなったため、
Windowsアプリケーションでも、コンソールアプリケーションでも動作がうまくいかない問題に直面しています。
(詳しくは追記を見てください。)
私のソースコードはどのような動作をしているのでしょうか。
該当のソースコード
追記の方を見てください。
Windows アプリケーションの場合
csharp
1using System; 2using System.Runtime.InteropServices; 3using System.Windows.Forms; 4 5namespace WindowsFormsAppTest 6{ 7 public partial class Form1 : Form 8 { 9 public ParseResult parseResult; 10 11 12 public Form1() 13 { 14 InitializeComponent(); 15 16 parseResult = new ParseResult(); 17 MainForm_Load(); 18 } 19 20 public void MainForm_Load() 21 { 22 webBrowser1.DocumentText = @" 23<html> 24<head> 25 <meta charset=""utf-8"" /> 26 <meta http-equiv=""X-UA-Compatible"" content=""IE=11"" /> 27 <title>タイトル</title> 28</head> 29<body> 30 <script> 31 function cs_func(text, mode) { 32 window.external.Result = ""Hello, world!""; 33 } 34 </script> 35 <h1>Hello!</h1> 36</body> 37</html> 38"; 39 webBrowser1.ObjectForScripting = parseResult; 40 } 41 42 [ComVisible(true)] 43 public class ParseResult 44 { 45 public string Result { get; set; } 46 public void SetResult(string s) { Result = s; } 47 } 48 49 private void button1_Click(object sender, EventArgs e) 50 { 51 webBrowser1.Document.InvokeScript("cs_func", new string[] { "test", "test 2" }); 52 Console.WriteLine(parseResult.Result); 53 } 54 } 55}
Button1を押すと、button1_click
が呼び出され、コンソールにHello, world!
と表示されます。
コンソールアプリケーションの場合
csharp
1using System; 2using System.Runtime.InteropServices; 3using System.Windows.Forms; 4 5namespace LojbanParser 6{ 7 8 public class LojbanParser 9 { 10 public string Text { get; set; } 11 public object Result { get; private set; } 12 public WebBrowser WebBrowser { get; } = new WebBrowser(); 13 public LojbanParser() { } 14 public LojbanParser(string text) { Text = text; } 15 public string Parse() 16 { 17 var parse = new ParseResult(); 18 WebBrowser.DocumentText = @" 19<html> 20<head> 21 <meta charset=""utf-8"" /> 22 <meta http-equiv=""X-UA-Compatible"" content=""IE=11"" /> 23 <title>title</title> 24</head> 25<body> 26 <script> 27 function cs_func(text, mode) { 28 external.Result = ""Hello, world!""; 29 } 30 </script> 31 <h1>Hello!</h1> 32</body> 33</html> 34"; 35 WebBrowser.ObjectForScripting = parse; 36 WebBrowser.Document.InvokeScript("cs_func", new string[] { "test", "test 2" }); 37 return parse.Result; 38 } 39 40 [ComVisible(true)] 41 public class ParseResult 42 { 43 public string Result { get; set; } 44 } 45 } 46 47 class Program 48 { 49 [STAThread] 50 static void Main(string[] args) 51 { 52 var parser = new LojbanParser(); 53 var result = parser.Parse(); 54 Console.WriteLine(result ?? "(null)"); 55 } 56 } 57}
(null)
と表示されます。
追記
Zuishinさんの指摘により、ソースコードを同じにしてみようとしてみました。
まずコンソールアプリケーションの場合です。
コンソールアプリケーションのときは参照から「System.Windows.Forms」を追加しなければなりません。
csharp
1using System; 2using System.Runtime.InteropServices; 3using System.Windows.Forms; 4 5namespace ConsoleApp1 6{ 7 class Program 8 { 9 [STAThread] 10 static void Main(string[] args) 11 { 12 var parser = new MyClass(); 13 var result = parser.Parse(); 14 Console.WriteLine(result ?? "(null)"); 15 } 16 } 17 18 public class MyClass 19 { 20 public string Text { get; set; } 21 public object Result { get; private set; } 22 public WebBrowser WebBrowser { get; } = new WebBrowser(); 23 public ParseResult ParseResultObject { get; set; } = new ParseResult(); 24 public string Parse() 25 { 26 WebBrowser.DocumentText = @" 27<html> 28<head> 29 <meta charset=""utf-8"" /> 30 <meta http-equiv=""X-UA-Compatible"" content=""IE=11"" /> 31 <title>title</title> 32</head> 33<body> 34 <script> 35 function cs_func(text) { 36 external.Result = text; 37 } 38 </script> 39 <h1>Hello!</h1> 40</body> 41</html> 42"; 43 WebBrowser.ObjectForScripting = ParseResultObject; 44 WebBrowser.Document.InvokeScript("cs_func", new string[] { "Hello, world!" }); 45 return ParseResultObject.Result; 46 } 47 48 [ComVisible(true)] 49 public class ParseResult 50 { 51 public string Result { get; set; } 52 } 53 } 54}
次にWindows アプリケーションです。
Form1に同じようなコードを書いてみたところ、
Windows アプリケーションでも(null)
が表示されるようになってしまいました。
csharp
1using System; 2using System.Runtime.InteropServices; 3using System.Windows.Forms; 4 5namespace WindowsFormsApp1 6{ 7 public partial class Form1 : Form 8 { 9 public MyClass Parser; 10 11 public Form1() 12 { 13 InitializeComponent(); 14 Parser = new MyClass(); 15 var result = Parser.Parse(); 16 Console.WriteLine(result ?? "(null)"); 17 } 18 } 19 20 public class MyClass 21 { 22 public string Text { get; set; } 23 public object Result { get; private set; } 24 public WebBrowser WebBrowser { get; set; } = new WebBrowser(); 25 public ParseResult ParseResultObject { get; set; } = new ParseResult(); 26 public string Parse() 27 { 28 WebBrowser.DocumentText = @" 29<html> 30<head> 31 <meta charset=""utf-8"" /> 32 <meta http-equiv=""X-UA-Compatible"" content=""IE=11"" /> 33 <title>title</title> 34</head> 35<body> 36 <script> 37 function cs_func(text) { 38 external.Result = text; 39 } 40 </script> 41 <h1>Hello!</h1> 42</body> 43</html> 44"; 45 WebBrowser.ObjectForScripting = ParseResultObject; 46 WebBrowser.Document.InvokeScript("cs_func", new string[] { "Hello, world!" }); 47 return ParseResultObject.Result; 48 } 49 50 [ComVisible(true)] 51 public class ParseResult 52 { 53 public string Result { get; set; } 54 } 55 } 56}
しかし、Form1の上にボタンを設置し、クリックしたときに処理するようコードを変更したところ、
1回だけ押した時は(null)
と表示され、2回目以降はHello, world!
と表示されるといった不安定な感じで表示されるようになりました。
csharp
1using System; 2using System.Runtime.InteropServices; 3using System.Windows.Forms; 4 5namespace WindowsFormsApp1 6{ 7 public partial class Form1 : Form 8 { 9 public MyClass Parser; 10 11 public Form1() 12 { 13 InitializeComponent(); 14 Parser = new MyClass(); 15 } 16 17 // ここに追加しました。 18 private void Button_Click(object sender, EventArgs e) 19 { 20 var result = Parser.Parse(); 21 Console.WriteLine(result ?? "(null)"); 22 } 23 } 24 25 public class MyClass 26 { 27 public string Text { get; set; } 28 public object Result { get; private set; } 29 public WebBrowser WebBrowser { get; set; } = new WebBrowser(); 30 public ParseResult ParseResultObject { get; set; } = new ParseResult(); 31 public string Parse() 32 { 33 WebBrowser.DocumentText = @" 34<html> 35<head> 36 <meta charset=""utf-8"" /> 37 <meta http-equiv=""X-UA-Compatible"" content=""IE=11"" /> 38 <title>title</title> 39</head> 40<body> 41 <script> 42 function cs_func(text) { 43 external.Result = text; 44 } 45 </script> 46 <h1>Hello!</h1> 47</body> 48</html> 49"; 50 WebBrowser.ObjectForScripting = ParseResultObject; 51 WebBrowser.Document.InvokeScript("cs_func", new string[] { "Hello, world!" }); 52 return ParseResultObject.Result; 53 } 54 55 [ComVisible(true)] 56 public class ParseResult 57 { 58 public string Result { get; set; } 59 } 60 } 61}
全くもって原因が分かりません。
おそらく、Java Scriptの方には問題がない(上記に示すように不安定だが動くときは動くので)とは思うのですが、
原因と対処法を教えていただきたいです。
補足情報
ターゲットフレームワーク: .NET Framework 4.7.1
IDE: Visual Studio 2017
OS: Windows 10

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/17 04:08
2019/03/17 04:12
2019/03/17 05:39 編集
2019/03/17 09:02