(ソース+バイナリ) ブラウザのアドレスバーからコマンド入力![]() 起動するとタスクバーに常駐します。 ブラウザのアドレスバーにコマンドを入力して、http 通信でアプリケーションを起動します。 ブラウザで無くても、http プロトコルであれば他のプロセスからのリクエクストを受けて 処理を行います 例えば、Flex AIR では、ローカルのアプリケーションを起動できませんが、 http 通信は可能なので運用の幅が広がると思います。 ![]() 終了は、上記ポップアップメニューで終了するか、http://pc名:50000/quit を送信します ソースコードVB.NET を利用する為のサンプルコードとして有用です 1) タスクバーに常駐 2) ポップアップメニュー 3) スレッド 4) http サーバー 5) http 経由でのスレッド終了 通常であれば作成される Form1.Designer.vb は削除してあります ( ここでは Form を使用しないので ) ※ myNotifyIcon.Dispose() でタスクバーのアイコンの終了処理をしないと ※ アイコンが自動的に表示上削除されません #Region "Imports はもともとプロジェクトで利用可能な名前を修飾する必要がなくなるだけです" Imports System.Net Imports System.Net.Sockets Imports System.Text Imports System.Diagnostics Imports System.Windows.Forms Imports System.Threading #End Region Public Class Form1 Inherits System.Windows.Forms.Form <System.STAThread()> _ Public Shared Sub Main() System.Windows.Forms.Application.Run(New Form1) End Sub 'Main Private components As System.ComponentModel.IContainer Private myContextMenu As ContextMenu Friend WithEvents myMenuItem As MenuItem Friend WithEvents myNotifyIcon As NotifyIcon ' ************************************************************ ' コンストラクタ ' MSDN の見本通りに常駐タスクバーに入る処理 ' ************************************************************ Public Sub New() components = New System.ComponentModel.Container() myContextMenu = New ContextMenu() myMenuItem = New MenuItem() myContextMenu.MenuItems.AddRange(New MenuItem() {myMenuItem}) myMenuItem.Index = 0 myMenuItem.Text = "終了" myNotifyIcon = New NotifyIcon(components) myNotifyIcon.Icon = New Icon("db.ico") myNotifyIcon.Text = "lightbox コマンドサーバー" myNotifyIcon.Visible = True myNotifyIcon.ContextMenu = myContextMenu MyBase.ShowInTaskbar = False ' とりあえず見えない MyBase.WindowState = FormWindowState.Minimized MyBase.Opacity = 0 End Sub ' ************************************************************ ' サーバースレッド開始 ' ************************************************************ Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' スレッド開始 Dim ThreadServer As New Thread(AddressOf ThreadEntry) ThreadServer.Start() End Sub ' ************************************************************ ' 特に使っていない ' ************************************************************ Private Sub InitializeComponent() Me.SuspendLayout() ' 'Form1 ' Me.ClientSize = New System.Drawing.Size(292, 273) Me.Name = "Form1" Me.ResumeLayout(False) End Sub ' ************************************************************ ' 終了用 ' ************************************************************ Private Sub menuItem1_Click(ByVal Sender As Object, _ ByVal e As EventArgs) Handles myMenuItem.Click ' スレッドに終了を伝える Dim hostname = System.Net.Dns.GetHostName() Dim command As New System.Net.WebClient() command.OpenRead("http://" + hostname + ":50000/quit") End Sub ' ************************************************************ ' 完全に非表示 ' ************************************************************ Private Sub Form1_Shown(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Shown Me.Visible = False End Sub ' ************************************************************ ' スレッドの入り口 ' ************************************************************ Private Sub ThreadEntry() Dim server As TcpListener = Nothing Try ' 50000 番ポート使用 Dim port As Int32 = 50000 ' ローカル Dim hostname = System.Net.Dns.GetHostName() Dim he As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(hostname) Dim iptop As System.Net.IPAddress = he.AddressList(0) Dim localAddr As IPAddress = IPAddress.Parse(iptop.ToString()) Dim header As String = _ "HTTP/1.1 200 OK" + ControlChars.CrLf + _ "Content-Type: text/plain; Charset=shift_jis" + ControlChars.CrLf + _ "Expires: Wed, 31 May 2000 14:59:58 GMT" + ControlChars.CrLf + ControlChars.CrLf + _ "lightbox コマンドサーバー" + ControlChars.CrLf + _ "( 使用方法 http://pc名:50000/コマンド または http://pc名:50000/コマンド|引数 )" + ControlChars.CrLf + _ "※ http://pc名:50000/quit でサービス終了" + ControlChars.CrLf + _ "※ URLエンコードは UTF8 で引き渡します" + ControlChars.CrLf + _ "※ 空白は %20 で引き渡します" + ControlChars.CrLf + _ "※ ファイルのパスは ダブルクォートで囲むと、拡張子による実行をブラウザが行いません" + ControlChars.CrLf server = New TcpListener(localAddr, port) ' サーバー開始 server.Start() ' 読み込みバッファ Dim bytes(1024) As Byte ' コマンドワーク Dim data As String = Nothing ' レスポンスワーク Dim ret As String = Nothing ' ********************************************** ' コマンド待ちのループ ' ********************************************** Do While True ' サービス終了 If data = "quit" Then Exit Do End If Console.WriteLine("Waiting ... ") ' 待機( 接続されると次の行へ ) Dim client As TcpClient = server.AcceptTcpClient() ' 受信したので処理開始 Console.WriteLine("Connected") data = "" ' 受信用ストリーム Dim stream As NetworkStream = client.GetStream() Dim i As Integer Dim cd As Integer = 0 ' ストリームからデータを取得( 初回 ) i = stream.Read(bytes, 0, bytes.Length) ' ********************************************** ' データ読み込みのループ ' 改行(\r\n)を見つけると、それまでに取得した ' 文字列( data )をコマンドとして実行する ' ********************************************** Do While i <> 0 cd = 0 ret = "" ' 読み込んだデータの1バイト(8ビット符号なし整数)サーチ For idx As Integer = 0 To i - 1 ' 改行の始まり(\r)発見 If bytes(idx) = &HD Then cd += 1 End If ' 通常の文字列データ( data )の作成 If cd = 0 Then data += _ Encoding.ASCII.GetString(bytes, idx, 1) End If ' 改行区切り(\n)でコマンドを取得 If bytes(idx) = &HA And cd = 1 Then ' URL エンコードは UTF8 で data = data.Replace("%20", "@") data = System.Web.HttpUtility.UrlDecode(data) ret += data + ControlChars.CrLf Console.WriteLine("Received: {0}", data) Dim Command As String() = data.Split(" ") If Command(0) = "GET" Then data = Command(1).Substring(1) data = data.Replace("@", " ") Console.WriteLine("Command: {0}", data) ' サービス終了 If data = "quit" Then Dim msg As Byte() = _ Encoding.GetEncoding(932).GetBytes( _ header + "● quit コマンドにより、サービスを終了しました") stream.Write(msg, 0, msg.Length) Exit Do End If ' コマンドと引数の区切りの処理 Dim delimStr As String = "|" Dim delimiter As Char() = delimStr.ToCharArray() ' 配列定義 Dim split As String() = Nothing ' トークン分割 split = data.Split(delimiter) Try ' 引数無し If split.Length = 1 Then ret += "【実行】" + data + ControlChars.CrLf Process.Start(data) Else ' 引数あり ret += "【実行】" + split(0) + " " + split(1) + ControlChars.CrLf Process.Start(split(0), split(1)) End If Catch ex As System.ComponentModel.Win32Exception ret += "【ERROR】" + ex.Message + ControlChars.CrLf End Try End If ' 1行のコマンド処理が終了したので、変数を初期化 cd = 0 data = "" 'Exit For End If Next If data = "" Then ' OK を返す Dim msg As Byte() = _ Encoding.GetEncoding(932).GetBytes( _ header + ret) stream.Write(msg, 0, msg.Length) Exit Do End If ' ********************************************** ' ストリームからデータを取得 ' 改行を見つけられず、データが残っている場合 ' ********************************************** i = stream.Read(bytes, 0, bytes.Length) Loop ' 処理終了で接続解除してサービス終了 client.Close() Loop Catch ex As SocketException Console.WriteLine("SocketException: {0}", ex) Finally server.Stop() End Try ' タスクバーのアイコンを開放 myNotifyIcon.Dispose() ' アプリケーション終了 System.Windows.Forms.Application.Exit() End Sub End Class |