SQLの窓

2013年09月20日


VS2012 Formアプリ(C#) : 通知領域で常駐する HttpServer テンプレート

SkyDrive へ移動

※ VS2012 用



ベースは Form アプリケーションです。本体を非表示にする状態と本体を表示にする状態を通知領域のアイコンを右クリックして表示されるメニューから切り替えれます。

機能としては、ブラウザのアドレスバーの内容を受信してブラウザに返し、本体ではデバッグ表示を行っています。本来の目的は、データベースのデータを更新したり、JSON で返す データベースサーバのテスト用アプリを想定しています。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;

namespace HttpServer
{
	public partial class Form1 : Form
	{

		// メニュー用オブジェクト
		private ContextMenu myContextMenu = null;
		private MenuItem myMenuItem1 = null;
		private MenuItem myMenuItem2 = null;
		private MenuItem myMenuItem3 = null;
		private NotifyIcon myNotifyIcon = null;

		public Form1()
		{
			InitializeComponent();

			// メニュー用のインスタンス作成
			myContextMenu = new ContextMenu();
			myMenuItem1 = new MenuItem();
			myMenuItem2 = new MenuItem();
			myMenuItem3 = new MenuItem();
			// コンテキストメニューにメニュー項目を一つ追加
			myContextMenu.MenuItems.AddRange(new MenuItem[] {
				myMenuItem1, myMenuItem2,myMenuItem3
			});
			// ******************************************
			// メニュー項目1の設定
			// ******************************************
			myMenuItem1.Index = 0;		// 親メニュー内のメニュー項目の位置
			myMenuItem1.Text = "終了";
			// 終了処理
			myMenuItem1.Click += async (Object sender,EventArgs e) => {
				HttpClient client = new HttpClient();
				try
				{
					await client.GetStringAsync("http://localhost:8080/q");
				}
				catch (Exception ex)	{
					Debug.WriteLine(ex.Message);
				}
				client.Dispose();
				myNotifyIcon.Visible = false;
				myNotifyIcon.Dispose();
				Thread.Sleep(5000);
				System.Windows.Forms.Application.Exit(); 

			};
			// ******************************************
			// メニュー項目2の設定
			// ******************************************
			myMenuItem2.Index = 1;		// 親メニュー内のメニュー項目の位置
			myMenuItem2.Text = "非表示";
			// 終了処理
			myMenuItem2.Click += (Object sender, EventArgs e) =>
			{
				this.ShowInTaskbar = false;	// タスク バーに表示しない
				this.WindowState = FormWindowState.Minimized;	// 最小化
				this.Opacity = 0;	// 透明
			};
			// ******************************************
			// メニュー項目3の設定
			// ******************************************
			myMenuItem3.Index = 2;		// 親メニュー内のメニュー項目の位置
			myMenuItem3.Text = "表示";
			// 終了処理
			myMenuItem3.Click += (Object sender, EventArgs e) =>
			{
				this.ShowInTaskbar = true;	// タスク バーに表示
				this.WindowState = FormWindowState.Normal;	// 通常
				this.Opacity = 100;	// 不透明
			};

			// NotifyIcon : 通知領域にアイコンを作成するコンポーネント
			myNotifyIcon = new NotifyIcon(new Container());
			Assembly myAssembly = Assembly.GetExecutingAssembly();
			myNotifyIcon.Icon = new Icon("Server.ico");
			myNotifyIcon.Text = "lightbox コマンドサーバー";
			myNotifyIcon.Visible = true;
			// メニューをセット
			myNotifyIcon.ContextMenu = myContextMenu ;

		}

		// フォームの初期処理
		private void Form1_Load(object sender, EventArgs e)
		{
	        // スレッド開始  
			new Thread( () =>
			{

				// HTTP プロトコル用リスナー
				TcpListener tl = new TcpListener(System.Net.IPAddress.Any, 8080);
				tl.Start();

				TcpClient tcp = null;
				NetworkStream stream = null;
				StreamReader reader = null;
				StreamWriter writer = null;
				string line = null;
				string lineall = null;

				while (true)
				{
					// HTTP の受信待ち
					tcp = tl.AcceptTcpClient();

					// 以下は、受信した場合に処理されます
					// データの入り口 ( NetworkStream )
					stream = tcp.GetStream();

					// これが無いと Google Chrome は読み込まなかった
					Thread.Sleep(500);

					// ストリームを読み込むオブジェクトを取得
					reader = new StreamReader(stream);
					// writer = new StreamWriter(stream, Encoding.GetEncoding("shift_jis"));
					writer = new StreamWriter(stream, new UTF8Encoding(false));

					// 一回の受信で取得した全文字列
					lineall = "";

					if (stream.DataAvailable)
					{
						// 非同期で一行取得
						while (true)
						{
							line = reader.ReadLine();
							// 空でチェックするしかないようです。
							if (line == "")
							{
								break;
							}
							lineall += line + "\n";
						}
					}
					Debug.WriteLine(lineall);

					// HTTP プロトコルに従って、ヘッダと本文を返す
					writer.WriteLine("HTTP/1.1 200 OK");
					writer.WriteLine("Content-Type: text/plain; charset=utf-8");
					int length = Encoding.GetEncoding("utf-8").GetByteCount(lineall);
					writer.WriteLine("Content-Length: " + length);

					writer.WriteLine();
					writer.Write(lineall);

					// オブジェクトを閉じる
					writer.Close();
					reader.Close();
					stream.Close();
					if (lineall == "")
					{
						// Console.WriteLine("データがありません");
						continue;
					}

					// アドレスバーで、http://localhost:8080/q と入力した場合はスレッドを終了
					if (lineall.Length > 10)
					{
						if (lineall.Substring(0, 7) == "GET /q ")
						{
							tl.Stop();
							break;
						}
					}
				}

				Debug.WriteLine("スレッドを終了します");
				myNotifyIcon.Visible = false;
				myNotifyIcon.Dispose();
				Thread.Sleep(5000);
				System.Windows.Forms.Application.Exit(); 

			}).Start();

		}
	}
}

関連する記事

Framework4.5(C#) のコンソールアプリケーションで、とても簡単に HTTP サーバーを作成できます


【VS(C#)の最新記事】
posted by lightbox at 2013-09-20 21:05 | VS(C#) | このブログの読者になる | 更新情報をチェックする
バッチ処理

Microsoft Office
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり