質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

2回答

4300閲覧

C#のコンソールアプリケーションでWebBrowserとのやり取りができない

skytomo

総合スコア35

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2019/03/17 03:26

編集2019/03/17 06:17

前提・実現したいこと

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

その前に両者のコードが同じものじゃないんですが。
window あたりが怪しくありませんか?

追記

結論から言えば、メッセージループが必要だったので、コンソールアプリでも Form を作る必要がありました。
以下がコンソールアプリでのサンプルコードです。
WebBrowser.ObjectForScripting Property を参考にしました。

C#

1using System; 2using System.Drawing; 3using System.Drawing.Drawing2D; 4using System.Runtime.InteropServices; 5using System.Security.Permissions; 6using System.Windows.Forms; 7 8namespace ConsoleApp1 9{ 10 class Program 11 { 12 [STAThread] 13 static void Main(string[] args) 14 { 15 var result = ParserForm.Parse("Hello World"); 16 Console.WriteLine(result ?? "(null)"); 17 Console.ReadKey(); 18 } 19 } 20 21 [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 22 [ComVisibleAttribute(true)] 23 public class ParserForm : Form 24 { 25 public static string Parse(string message) 26 { 27 var region = new Region(new GraphicsPath()); 28 var form = new ParserForm 29 { 30 Visible = false, 31 message = message, 32 FormBorderStyle = FormBorderStyle.None, 33 Region = region 34 }; 35 form.ShowDialog(); 36 return form.Result?.ToString(); 37 } 38 39 private WebBrowser webBrowser1 = new WebBrowser(); 40 private string message; 41 public object Result { get; set; } 42 43 public ParserForm() 44 { 45 webBrowser1.Dock = DockStyle.Fill; 46 Controls.Add(webBrowser1); 47 Load += (s, e) => 48 { 49 webBrowser1.ObjectForScripting = this; 50 webBrowser1.DocumentText = @" 51<html> 52<head> 53 <meta charset=""utf-8"" /> 54 <meta http-equiv=""X-UA-Compatible"" content=""IE=11"" /> 55 <title>title</title> 56</head> 57<body> 58 <script> 59 function cs_func(text) { 60 window.external.Result = text; 61 } 62 </script> 63 <h1>Hello!</h1> 64</body> 65</html> 66"; 67 Application.DoEvents(); 68 webBrowser1.Document.InvokeScript("cs_func", new[] { message }); 69 DialogResult = DialogResult.OK; 70 }; 71 } 72 } 73}

投稿2019/03/17 03:59

編集2019/03/17 07:07
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

skytomo

2019/03/17 04:08

すみません、確かに Windows アプリケーションで、 `window.external.Result = ""Hello, world!"";` としていたのに対して、 コンソールアプリケーションで、 `external.Result = ""Hello, world!"";` としていたのは同じではありませんでした。 しかし、これらのコードを入れ替えても、 Window アプリケーションは動きましたが、 コンソールアプリケーションは動きませんでした。 つまり、`window`がついているかはあまり関係ないと思います。
Zuishin

2019/03/17 04:12

そこだけじゃありません。 まずどちらからでも同じ手順で呼び出せるコードを作り、同じものを使うよう試してください。 クラス化し、変数などはそのクラスのプロパティにして呼び出しと結果の取得だけをそれぞれのプロジェクトで行うようにしてください。 全てはこれができてからだと思います。だから私もざっと眺めただけで自分で検証していません。検証できる環境が整っていないからです。
skytomo

2019/03/17 05:39 編集

ソースコードを同じように変更してみました。 ただ、Windows アプリケーションでもうまくいかなくなってしまいました。 (追記のところに書きました)
skytomo

2019/03/17 09:02

ああ、ありがとうございます! ちゃんと動くようになりました
guest

0

たんに表示すべきFormがない、というだけかと。


単純にFormを追加したからといって、Formが表示できるようにはなりません。
Windowsのフォームというのはその背後にWindowsメッセージというなかなか膨大な(?)仕掛けが動いており、そいつも含めて実装する必要があります
まあ、手っ取り早いのは、Formアプリにするってことですが、コンソールアプリにメッセージループを実装するというのも、そんなに難しくないので挑戦してみてもいいかと思います。

「C# Form コンソールアプリ」なんかでぐぐると、両対応なアプリの作成法なんかもでてくるようなので読んでみてはどうでしょう

投稿2019/03/17 03:48

編集2019/03/17 05:53
y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

skytomo

2019/03/17 06:13

私がしたいことは**Web BrowserでJava Scriptを処理させ、C#で結果を受け取ること**です。 例えば、Java Scriptに足し算を依頼したいとします。 C#側はWeb Browserを通じてJava Scriptに1と2の数値を渡します。Java Scriptは計算して、3を返します。 C#側は3を受け取り、それをConsole.WriteLineで表示します。 つまり、フォームを表示したいのではありません。むしろ、フォームを表示せずにWeb Browserを通じてJava Scriptとやりとりをしたいのです。 フォームを表示せずにやりとりをしたいため、コンソールアプリケーションを選択しました。しかし、上記にも書いた通り、うまくいきません。
y_waiwai

2019/03/17 06:21

なら、コンソールアプリベースでどーこーしようというより、フォームを非表示にするとかヘッドレスブラウザを使うとか言う方向のほうがいいような気がしますがどうでしょう。 #コンソールアプリベースでブラウザを開発するんだ!ってのは不可能ではないですが。。
skytomo

2019/03/17 07:01

返信ありがとうございます。 ヘッドレスブラウザは知りませんでした。 おそらく、それを使えばやりたいことはできるかもしれません。 ちょっとやってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問