|
(ソース+バイナリ) ブラウザのアドレスバーからコマンド入力
起動するとタスクバーに常駐します。 ブラウザのアドレスバーにコマンドを入力して、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
|