ページ 11

バッチファイルと同等のことをするプログラム

Posted: 2016年4月25日(月) 23:42
by baby2478nishi
たびたびすみません。

Minecraftというゲームのサーバーはbatファイルから起動するのですがそれをプログラム(C#/XAML)から行い、その後表示される子マンドプロンプトをGUIプログラムに映したいです。
ただし、コマンドプロンプトを起動させずに、ということでお願いします。(プログラム自体がcmdの機能も持つみたいなイメージ)

Re: バッチファイルと同等のことをするプログラム

Posted: 2016年4月26日(火) 00:30
by みけCAT
baby2478nishi さんが書きました:Minecraftというゲームのサーバーはbatファイルから起動するのですがそれをプログラム(C#/XAML)から行い、その後表示される子マンドプロンプトをGUIプログラムに映したいです。
へー、そうなんですね。
日記は質問掲示板ではなく、日記に書いた方がいいでしょう。
baby2478nishi さんが書きました:ただし、コマンドプロンプトを起動させずに、ということでお願いします。
何をお願いされたのか、よくわかりません。

Re: バッチファイルと同等のことをするプログラム

Posted: 2016年4月26日(火) 19:12
by can110
Minecraftについては知りませんが、件のバッチファイルは単に.jarのサーバプログラムを起動しているだけでしょうか?
であれば、以下の方法で、サーバプログラムの標準出力をリダイレクトすることができます。

[C#] 非同期で標準出力(コンソールアプリケーション)の内容をプログラムで受け取る

以下は、上記を参考にしたWindowsフォームアプリケーションの例です。
適当なサーバ(Sv.jar)を起動し、サーバの標準出力をテキストボックスに追記します。

コード:

using System;
using System.Windows.Forms;
using System.Diagnostics;

namespace StdOut
{
    public partial class Form1 : Form
    {
        public delegate void MyEventHandler(object sender, DataReceivedEventArgs e);
        public event MyEventHandler m_myEvent = null;
        Process m_process = null;

        public Form1()
        {
            InitializeComponent();
        }

        // サーバ起動
        private void btnExec_Click(object sender, EventArgs e)
        {
            m_myEvent = new MyEventHandler(event_DataReceived);

            m_process = new Process();

            // 起動したい.jarファイルのある場所=EXEと同じ場所とする
            string jarDir = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

            // 適切な引数にて.jarファイルを実行する
            // Sv.jar は適当なサーバプログラム
            m_process.StartInfo.FileName = "java";
            m_process.StartInfo.Arguments = " -jar \"" + jarDir + "\\Sv.jar\" 8079";

            m_process.StartInfo.CreateNoWindow = true;  // ウインドウは非表示とする
            m_process.StartInfo.UseShellExecute = false;
            m_process.StartInfo.RedirectStandardOutput = true; // 標準出力をリダイレクト
            m_process.OutputDataReceived += new DataReceivedEventHandler( process_DataReceived);

            m_process.Start();
            m_process.BeginOutputReadLine();
        }

        void event_DataReceived(object sender, DataReceivedEventArgs e)
        {
            // とりあえずテキストボックスに追記
            tb1.Text += e.Data + "\r\n";
        }

        void process_DataReceived(object sender, DataReceivedEventArgs e)
        {
            // UIのハンドラへ
            this.Invoke(m_myEvent, new object[2] { sender, e });
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                if (m_process != null)
                {
                    m_process.Kill();
                    m_process.Close();
                    m_process.Dispose();
                }
            }
            catch (InvalidOperationException exc)
            {
                Debug.WriteLine( exc.Message);
            }
        }
    }
}


Re: バッチファイルと同等のことをするプログラム

Posted: 2016年4月26日(火) 20:32
by baby2478nishi
can110さん、ありがとうございます。
とりあえず、WPFに移行させて頑張ってみます!

Re: バッチファイルと同等のことをするプログラム

Posted: 2016年4月26日(火) 21:23
by baby2478nishi
移行させようとしてみたのですがうまくいきません。

コード:

//MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Security;
using System.Collections;
using System.Net;
using System.Threading;
using System.Diagnostics;
using UPNPLib;


    
namespace WPF
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public delegate void MyEventHandler(object sender, DataReceivedEventArgs e);
        public event MyEventHandler m_myEvent = null;
        Process m_process = null;
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            this.info1.DataContext = "Booting…";
            m_myEvent = new MyEventHandler(event_DataReceived);

            m_process = new Process();

            // 起動したい.jarファイルのある場所=EXEと同じ場所とする
            string jarDir = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

            // 適切な引数にて.jarファイルを実行する
            // Sv.jar は適当なサーバプログラム
            m_process.StartInfo.FileName = "java";
            m_process.StartInfo.Arguments = " -jar \"" + jarDir + "\\Sv.jar\" 8079";

            m_process.StartInfo.CreateNoWindow = true;  // ウインドウは非表示とする
            m_process.StartInfo.UseShellExecute = false;
            m_process.StartInfo.RedirectStandardOutput = true; // 標準出力をリダイレクト
            m_process.OutputDataReceived += new DataReceivedEventHandler(process_DataReceived);

            m_process.Start();
            m_process.BeginOutputReadLine();
        }
        private void button_Copy_Click(object sender, RoutedEventArgs e)
        {
            this.info1.DataContext = "Closing…";
        }

        private void button_Click_1(object sender, RoutedEventArgs e)
        {
            this.info1.DataContext = "Restarting…";
        }

        private void button_Click_2(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void settings_Click(object sender, RoutedEventArgs e)
        {
            var win = new Settings1();
            win.Show();
        }

        private void button_Click_3(object sender, RoutedEventArgs e)
        {

        }

        private void test_Click(object sender, RoutedEventArgs e)
        {
            /*int p_ip;
            p_ip = 1;
            IUPnPAddressFamilyControl.GetAddressFamily(out p_ip);
            this.info1.DataContext = "IPアドレス:";*/
        }
    }
}
移行後がこちらなのですが、
重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
エラー CS0117 'Application' に 'ExecutablePath' の定義がありません WPF F:\WPF\WPF\WPF\MainWindow.xaml.cs 50 アクティブ
エラー CS0103 現在のコンテキストに 'process_DataReceived' という名前は存在しません。 WPF F:\WPF\WPF\WPF\MainWindow.xaml.cs 60 アクティブ
エラー CS0103 現在のコンテキストに 'event_DataReceived' という名前は存在しません。 WPF F:\WPF\WPF\WPF\MainWindow.xaml.cs 45 アクティブ
というエラーが出ます。(現段階でこのエラーが出たので途中までです。)

どこか足らないところありますか?

Re: バッチファイルと同等のことをするプログラム

Posted: 2016年4月26日(火) 21:55
by YuO
そのまんまだと思いますが……。
baby2478nishi さんが書きました:エラー CS0117 'Application' に 'ExecutablePath' の定義がありません WPF F:\WPF\WPF\WPF\MainWindow.xaml.cs 50 アクティブ
System.Windows.Forms.ApplicationExecutablePathは存在しますが、System.Windows.Applicationには存在しません。
WPFに内のは、単純にWinFormsのApplicationクラスの役割が大きすぎる、ということかと思います。
普通に、System.Reflection.Assembly.GetEntryAssemblyから、LocationなりCodeBaseなりで取得するようにすればよいので。
baby2478nishi さんが書きました:エラー CS0103 現在のコンテキストに 'process_DataReceived' という名前は存在しません。 WPF F:\WPF\WPF\WPF\MainWindow.xaml.cs 60 アクティブ
エラー CS0103 現在のコンテキストに 'event_DataReceived' という名前は存在しません。 WPF F:\WPF\WPF\WPF\MainWindow.xaml.cs 45 アクティブ
そのまま、これらの名前のメソッドが存在していません。can110さんのコードにはこれらのメソッドが存在します。
イベントハンドラ系も簡単な物は面倒だからラムダ式で、もよくありますが……。

Re: バッチファイルと同等のことをするプログラム

Posted: 2016年4月26日(火) 23:51
by baby2478nishi
これらの名前のメソッドが存在していません。
とはどういうことでしょうか?

コード:

m_myEvent = new MyEventHandler(event_DataReceived);
            m_process.OutputDataReceived += new DataReceivedEventHandler(process_DataReceived);
ではだめなのですか?

Re: バッチファイルと同等のことをするプログラム

Posted: 2016年4月27日(水) 09:44
by YuO
YuO さんが書きました:WPFに内のは、単純にWinFormsのApplicationクラスの役割が大きすぎる、ということかと思います。
eratta: s/内/無い/
baby2478nishi さんが書きました:
これらの名前のメソッドが存在していません。
とはどういうことでしょうか?
そのまんまです。
baby2478nishi さんが書きました:

コード:

m_myEvent = new MyEventHandler(event_DataReceived);
            m_process.OutputDataReceived += new DataReceivedEventHandler(process_DataReceived);
ではだめなのですか?
どこにevent_DataReceivedという名前のメソッドが書かれているのですか。
どこにprocess_DataReceivedという名前のメソッドが書かれているのですか。
その2行は,デリゲートの生成と代入,デリゲートの生成とイベントの追加をそれぞれ行っているだけです。

メソッドが無いと言われて意味がわからないのであれば,自分にあうC#の入門書を1冊買ってきてそれを読んでください。
文法解説をし始めたらキリが無いので。

Re: バッチファイルと同等のことをするプログラム

Posted: 2016年4月27日(水) 18:02
by baby2478nishi
分かりました。ありがとうございます。