17th Embarcadero Developer Camp

Similar documents
21st Embarcadero Developer Camp

Microsoft PowerPoint - はじめてのDataSnapアプリケーション_

Microsoft PowerPoint - はじめてのDataSnapアプリケーション_

22nd Embarcadero Developer Camp G6

PowerPoint プレゼンテーション

A. InstallScript プロジェクト InstallScript インストールは InstallScript エンジンによって制御され 決められた順序で一連のイベントが生成されます これらのイベントは インストールを実行するソフトウェアハンドラーをトリガーします たとえば インストールがロ

プロセス間通信

Developer Camp

10th Developer Camp - B5

24th Embarcadero Developer Camp

知って得する!現役ヘルプデスクが答えるDelphiテクニカルエッセンス 9.0

1 シミュレーションとは何か?

開発者が知りたい実践プログラミングテクニック!

NortonAntiVirus for MicrosoftExchange

// このクラスの有効期間中の各呼び出しに使用される キャッシュされた Socket オブジェクト Socket socket = null; // 非同期処理が完了したことを通知するために信号を送るオブジェクト static ManualResetEvent clientdone = new Ma

「RAD Studio XE5によるマルチ言語/マルチデバイス開発の進め方」

知って得する!現役ヘルプデスクが答えるDelphiテクニカルエッセンス

項番 現象 原因 対応手順書など 4 代理店コードでのダウンロード時に以下のメッセージの画面が表示される サービス時間外のため 現在 このサービスはご利用になれません 当機能のサービス時間外です 以下の時間帯にダウンロードしてください 月曜日 ~ 金曜日 7:00~21:00 土曜日 7:00~17

スクールCOBOL2002

14th Developer Camp

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

TFTP serverの実装

25th Developer Camp

ArcGIS Runtime SDK for .NET アプリケーション配布ガイド

25th Developer Camp

これらの情報は 外部に登録 / 保存されることはございません 5 インターネット接続の画面が表示されます 次へ > ボタンをクリックしてください 管理者様へ御使用時に設定された内容を本説明文に加筆ください 特に指定不要で利用可能であった場合は チェックボックスを オフ していただきますようご案内くだ

TestDesign for Web

新OS使用時の留意事項

Embarcadero Developer Camp

Java講座

注意 インストール中に ユーザアカウント制御 ( 以下 UAC といいます ) の実行確認画面が表示されることがあります 表示された場合ははいをクリックして インストールを進めてください なお 管理者以外の場合 管理者への昇格を求める UAC 画面が表示される場合がありますので 管理者アカウントのパ

新バージョンDelphi/400 XE7ご紹介 - マルチデバイスデザイナ機能で開発効率アップ! -

知って得する!現役ヘルプデスクが答えるDelphiテクニカルエッセンス 8.0

Windows GPO のスクリプトと Cisco NAC 相互運用性

MxLogonサーバサイドツールキット用UI

(1)IE6 の設定手順 (1)IE6 の設定手順 1) 信頼済みサイトの追加手順 1: ブラウザ (Internet Explorer) を起動します 手順 2: ツール / インターネットオプション / セキュリティ メニューを選択します 手順 3: セキュリティ タブの 信頼済みサイト を選択

MAPインストーラー起動時のエラーメッセージへの対処方法

Windows 10の注意点

Delphi/400開発ノウハウお教えします 「メニュー」開発のテクニック

SAMBA Stunnel(Windows) 編 1. インストール 1 セキュア SAMBA の URL にアクセスし ログインを行います xxx 部分は会社様によって異なります xxxxx 2 Windows 版ダウンロード ボ

UIOUSBCOM.DLLコマンドリファレンス

28th Embarcadero Developer Camp

Microsoft Word JA_revH.doc

Windows 7ファイル送信方法 SMB編

クイックセットアップ for モバイル(Windows)

IBM SPSS Amos インストール手順 (サイト ライセンス)

セキュリティオンライン Powered by Symantec インストールマニュアル 第 9 版 2016 年 7 月 19 日 1

WebReportCafe

手順書

パソコン決裁7 Business 試用版

Java言語 第1回

C#の基本

外周部だけ矩形配列

各種パスワードについて マイナンバー管理票では 3 種のパスワードを使用します (1) 読み取りパスワード Excel 機能の読み取りパスワードです 任意に設定可能です (2) 管理者パスワード マイナンバー管理表 の管理者のパスワードです 管理者パスワード はパスワードの流出を防ぐ目的で この操作

図 1 アドインに登録する メニューバーに [BAYONET] が追加されます 登録 : Excel 2007, 2010, 2013 の場合 1 Excel ブックを開きます Excel2007 の場合 左上の Office マークをクリックします 図 2 Office マーク (Excel 20

スライド 1

INS メイト V30Slim を Windows Vista がプレインストールされたパソコンでご使用になるお客様へ < ご案内 > 2007 年 4 月 このたびは INS メイト V30Slim をお買い求めいただき 誠にありがとうございます 本紙は INS メイト V30Slim を Win


クイックセットアップ for モバイル(Windows)

◎phpapi.indd

ステップアップ! モバイルアプリケーション開発

CentreCOM VT-Kit2 plus リリースノート

Delphi/400開発ノウハウお教えします 情報を守ろう!安全性を高めたWebシステムの構築

Delphi/400 テクニック公開 Windows7に最適化した アプリ開発・運用テクニック

939061j

クイックセットアップ for モバイル(iOS/Android)

PowerPoint プレゼンテーション

コンピュータ工学講義プリント (7 月 17 日 ) 今回の講義では フローチャートについて学ぶ フローチャートとはフローチャートは コンピュータプログラムの処理の流れを視覚的に表し 処理の全体像を把握しやすくするために書く図である 日本語では流れ図という 図 1 は ユーザーに 0 以上の整数 n

商標類 Microsoft は, 米国およびその他の国における米国 Microsoft Corp. の登録商標です Microsoft Office は, 米国 Microsoft Corp. の商品名称です Microsoft Excel は, 米国 Microsoft Corp. の商品名称です

電子化シートマニュアル(インストール編)_ver106

SpringSecurity

SSL サムプリントの検証 SSL サムプリントの検証はリモートユーザーがホストの信頼性を検証するために使用します この検証はリモートとホスト間の接続の安全性を確立して MITM 攻撃から保護するために実行する必要があります デフォルトで リモートユーザーが TCP/IP を使用してホストに接続しよ

GHS混合物分類判定システムインストールマニュアル

Microsoft Word - ssVPN MacOS クライアントマニュアル_120版.doc

1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String

Microsoft Word - Qsync設定の手引き.docx

ご利用のコンピュータを設定する方法 このラボの作業を行うには 事前設定された dcloud ラボを使用するか 自身のコンピュータをセットアップします 詳細については イベントの事前準備 [ 英語 ] とラボの設定 [ 英語 ] の両方のモジュールを参照してください Python を使用した Spar

マイフォルダへのアクセス マイフォルダ をクリックすると マイフォルダの一覧画面へ遷移します 利用の手引き ver.5 フォルダの作成 新規フォルダ をクリックして フォルダ名を入力し 作成 ボタンをクリックする ファイルのアップロード ファイルをアップロードしたいフォルダをクリックして開き アップ

Maple 12 Windows版シングルユーザ/ネットワークライセンス

2/25 1 クライアントソフトウェアのインストールと設定 (1) ハードディスクインストール 1 クライアントソフトウェアのダウンロードと実行 2 インストールの開始 [ 次へ ] を押下します

目次 はじめに 4 概要 4 背景 4 対象 5 スケジュール 5 目標点 6 使用機材 6 第 1 章 C# 言語 7 C# 言語の歴史 7 基本構文 8 C 言語との違い 9 Java 言語との違い 10.Netフレームワーク 10 開発資料 10 第 2 章 Mono 11 Monoの歴史 1


Transcription:

17 Th Developer Camp B3 Delphi/C++ テクニカルセッション Windows サービスアプリケーションの作成と連携アプリケーションへの応用 株式会社シリアルゲームズ取締役 細川淳 1

17 Th Developer Camp 1 Windows サービスについて 2

Windows サービスとは ログインせずに動作できます ユーザーは LOCAL_SERVICE など特別なユーザーとして実行されます 自動的に起動できます バックグラウンドで動作し続けます 3

Windows サービスとは UI を持たないアプリケーション デスクトップとの対話を許可 にチェックをいれれば GUI を表示することも可能です 4

Windows サービスとは これらの特徴からウェブサーバなどの UI を必要とせず かつ 必ず起動していなくてはならない用途に使われます 例 : BlackfishSQL サービスのプロパティ 5

17 Th Developer Camp 1 Delphi が 提供する機能 6

Delphi サービスプロジェクト ファイル 新規作成 その他 Delphi プロジェクト サービスアプリケーション としてサービスプロジェクトを作成可能です 7

Delphi サービスプロジェクト プロジェクトを作成すると見慣れたフォームのような物が表示されますが これは TDataModule を継承した TService です TDataModule を継承したクラスは RAD スタイルで開発可能です たとえば 非ビジュアルコンポーネントをドラッグ & ドロップして貼り付けておけます 今回作成するクラスでも TIdTCPServer を使用しています 8

Delphi サービスプロジェクト 9

TService のプロパティ TService は TForm と同じようにビジュアルコンポーネントなので 当然オブジェクトインスペクタ上でプロパティを設定できます 順に見ていきましょう 10

TService のプロパティ AllowStop: Boolean サービスが停止可能かどうかを設定します AllowPause: Boolean サービスが一時停止可能かどうかを設定します Dependencies: TDependencies サービスの依存関係を設定します たとえば ローカルネットワーク上のコンピュータのリストを必要とするサービスは コンピュータブラウザ サービスを必要とします DisplayName: String サービスの一覧に表示される名前です 11

TService のプロパティ ErrorSeverity: TErrorSeverity サービスが起動に失敗した場合の動作を定義します esignore エラーを記録して動作を続けます esnormal エラーを記録しメッセージを表示しますが動作は続けます essevere エラーを記録し最後に適切であった環境設定が起動中のみ動作を続けます それ以外の場合は最後に適切だった環境設定が起動されます escritical エラーを記録し最後に適切であった環境設定を代わりに起動します 現在の環境設定が最後だった場合は 起動に失敗します 12

TService のプロパティ Interactive: Boolean デスクトップとの対話が必要な場合に True にします LoadGroup: String ロードの順序をしめすグループの名前です 依存関係があるサービス同士の起動の順序を規定します Password: String サービスを実行するユーザーのパスワードです SYSTEM や LOCAL_SERVICE といったビルトインユーザーの場合は必要ありません ServiceStartName: String サービスを実行するユーザーの名前です 13

TService のプロパティ ServiceType: TServiceType サービスのタイプです stwin32 Win32 サービス stdevice デバイスドライバ stfilesystem ファイルシステムドライバ StartType: TStartType stboot ブートローダによって起動されます デバイスドライバなどです stsystem システムの初期化後に起動されます ファイルシステムなどです stauto Windows 起動後 自動的に起動します stmanual ユーザーが手動で起動します stdisabled 無効 サービスは起動しません TagID: DWord LoadGroup で使用される一意な値です 14

TService のイベント OnPause 一時中断時に呼ばれます OnContinue サービスの再開時に呼ばれます OnStart サービスの起動時に呼ばれます OnStop サービスの停止時に呼ばれます OnShutdown サービス終了時に呼ばれます 15

TService のイベント OnExecute サービスを実現するスレッドが開始されたときに呼ばれます 基本的にはメッセージループを記述する場所です ただし 本来はこのハンドラを記述する必要はありません TServiceThread がサービス関連のメッセージを適切に処理します このハンドラを記述する必要があるのは 独自のロギング機構を組み込む必要がある場合などです Windows からサービスの開始や停止などの際に 独自にログを出力したりできます これ以外に OnCreate OnDestroy などの普通のイベントも利用できます 16

TService のメソッド TService のメソッドは基本的には呼ぶ必要がありません TService や TServiceApplication が Windows に対しての応答などを適切に処理します ただし 1 つ便利なメソッドがあります LogMessage メソッドです このメソッドは EventLog にログを書き込みます サービスは UI を持たないため ログは非常に重要です 起動の状態などをこのメソッドを通じてイベントログにはき出せます try-except で補足したエラーをログにはき出せば エラーも特定できます ただし EventLog の形式で出力されるため テキストエディタなどで簡単にみたり ログを提出したりといった用途には向きません 17

TService のメソッド 18

TServiceApplication プロジェクトソースを見ると まるで普通のアプリケーションのようなコードになっています program BeepService; uses SvcMgr, umain in 'umain.pas' {servicebeep: TService}, ulog in 'ulog.pas'; {$R *.RES} begin if not Application.DelayInitialize or Application.Installing then Application.Initialize; Application.CreateForm(TserviceBeep, servicebeep); Application.Run; end. 19

TServiceApplication しかし この Application 変数は通常の TApplication ではなく TServiceApplication のインスタンスです TServiceApplication は 通常の TApplication ど同様にアプリケーションの制御を司ります Run メソッドで TService のインスタンスを起動し実行します この機構により プログラマはサービスの起動などのルーチンワークを組む必要なく サービスの根幹のみをコーディングできます 20

17 Th Developer Camp サービスの権限 21

サービスの権限 サービスはビルトインユーザーとして実行されることが ほとんどです サービスのユーザーを指定するには ドメインとユーザー名を指定します ビルトインアカウントは NT_AUTHORITY というドメインに属しています 表示名 System LocalSystem NetworkSystem 実際の名前 権限 NT_AUTHORITY SYSTEM Administrators グループと同じ NT_AUTHORITY LOCAL_SYSTEM Users グループと同じ NT_AUTHORITY NETWORK_SYSTEM 22

17 Th Developer Camp サービスとの 通信方法 23

通信方法 サービスとの通信にはいくつかの方法があります 通常のプロセス間通信の仕組みが全て使えます RemoteProcedureCall 名前付きパイプ ソケット などなどです 24

通信方法 - 注意点 サービスとクライアントプログラムは権限が違う サービスは SYSTEM や LOCAL_SERVICE といった高い権限をもって動作します サービスと接続するプログラムは通常 ログインしているユーザーの権限で動作します 通常はサービスの権限が高いため問題にはなりませんが 本来は取得できないハズの情報にまでアクセスできてしまうので注意が必要です そのような場合は 次スライドの名前付きパイプを使うか パスワードなどでアクセスしてきたプログラムの認証をする必要があります セキュリティの違うユーザーが高いセキュリティを持ったサービスと通信することで取得できないハズのデータを取得できてしまう! 25

通信方法 - 注意点 ユーザー権限が必要な場合 名前付きパイプを使うとパイプサーバ ( 今回はサービス ) は クライアントの権限で API を呼び出すことができます (Impersonate) セキュリティ以外にも ユーザーのプロファイルが必要な場合などに利用できます パイプ 名前付きパイプを使うとクライアントの権限で API を呼び出すため安全です 26

通信方法 Delphi には幸いなことに Indy がありますので ソケットを使う方法が一番簡単です 次に簡単なのは名前付きパイプでしょう しかし 名前付きパイプのクラスを作る必要があります 今回は もっとも簡単に使える TIdTCPServer と TIdTCPClient を使ってプログラムします クライアント A サービス クライアント B TCP/IP クライアント C 27

17 Th Developer Camp 実際のプログラム 28

作成するサービスについて 今回作成するサービスは以下のような動作とします TIdTCPServer で接続を待ち受けます TIdTCPServer で 'on' を受け取ると Beep 音を鳴らします TIdTCPService で 'off' を受け取ると Beep 音を消します ただこれだけの機能です 権限は SYSTEM とします 今回は敢えて OnExecute を実装し サービスの動作に迫ります 29

作成するサービスについて また せっかくなので WinRing0 を使いハードウェアを直接叩いて Beep を鳴らします WinRing0 は Crystal Dew World の hiyohiyo さんの著作物です ちなみに VCL の Beep 関数や Win32 API の Beep 関係の関数は サウンドボードでエミュレーションされている場合があり 実際にマザーボード上のスピーカーから音が出ないことがあります そのため このサービスでは WinRing0 を使用して直接ハードウェアを叩くことによって Beep 音を実現しています 30

OnCreate, OnDestroy procedure TserviceBeep.ServiceCreate(Sender: TObject); var i: Integer; begin FParams := TList.Create; ReadIni; FLog := TLog.Create(FLogDir, 'BeepService'); FLogAdapter := TLogAdapter.Create(FLog, ''); FLogAdapter.AddInfo('BeepService Created. ' + FExeName); for i := 0 to FParams.Count - 1 do with PBeepParam(FParams[i])^ do begin FLogAdapter.AddInfo( Format('Param%d Freq = %d Duration = %d', [i, Freq, Duration])); procedure TserviceBeep.ServiceDestroy(Sender: TObject); begin Clear; FParams.Free; FLogAdapter.AddInfo('BeepService Destroyed.'); OnCreate で初期化します OnStart でも初期化できますが OnStart はサービスの開始ごとに呼ばれるため注意が必要です ここでは設定をファイルから読み込み 独自のログシステムを生成しています また 同様に OnDestroy で終了処理を行います 31

OnExecute procedure TserviceBeep.ServiceExecute(Sender: TService); begin FLogAdapter.AddInfo('BeepService Executed.'); InitializeOls; try FLogAdapter.AddInfo('WinRing0 Status: ' + IntToStr(GetDllStatus)); tcpserver.defaultport := FPort; tcpserver.active := True; try while (not Terminated) do begin if (ProcessMessages) then Break; if (not Beep) then Sleep(200); finally tcpserver.active := False; finally DeinitializeOls; OnExecute のイベントハンドラです ここではメッセージループを作成し サービスが終了するまでループしています 32

ProcessMessages function TserviceBeep.ProcessMessages: Boolean; const ActionStr: array[1.. 5] of String = (SStop, SPause, SContinue, SInterrogate, SShutdown); var Msg: TMsg; OldStatus: TCurrentStatus; ErrorMsg: String; ActionOK: Boolean; begin Result := PeekMessage(Msg, 0, 0, 0, PM_REMOVE); if (not Result) then Exit; 33

ProcessMessages with Msg do if (hwnd = 0) and (message = CM_SERVICE_CONTROL_CODE) then begin OldStatus := Status; try Result := False; ActionOK := True; case wparam of SERVICE_CONTROL_STOP: begin ActionOK := DoStop; Result := ActionOK; SERVICE_CONTROL_PAUSE: begin ActionOK := DoPause; Result := False; SERVICE_CONTROL_CONTINUE: begin ActionOK := DoContinue; Result := False; 34

ProcessMessages SERVICE_CONTROL_SHUTDOWN: begin DoShutDown; Result := True; SERVICE_CONTROL_INTERROGATE: begin DoInterrogate; Result := False; LogMessage(ErrorMsg); end else DispatchMessage(msg); if (not ActionOK) then Status := OldStatus; except on E: Exception do begin if (wparam <> SERVICE_CONTROL_SHUTDOWN) then Status := OldStatus; if (wparam in [1.. 5]) then ErrorMsg := Format( SServiceFailed, [ActionStr[Integer(wParam)], E.Message]) else ErrorMsg := Format(SCustomError,[wParam, E.Message]); 35

OnConnect, OnDisconnect, OnException procedure TserviceBeep.tcpServerConnect(AContext: TIdContext); begin FLogAdapter.AddInfo('Connected by ' + AContext.Binding.PeerIP); procedure TserviceBeep.tcpServerDisconnect(AContext: TIdContext); begin FLogAdapter.AddInfo('Disconnected by ' + AContext.Binding.PeerIP); procedure TserviceBeep.tcpServerException(AContext: TIdContext; AException: Exception); begin FLogAdapter.AddWarning(AException.Message); 36

OnExecute procedure TserviceBeep.tcpServerExecute(AContext: TIdContext); var Str: String; begin if (AContext.Connection.IOHandler.Readable) then begin Str := AnsiLowerCase(Trim(AContext.Connection.IOHandler.ReadLn(#0))); FLogAdapter.AddInfo(Str + ' Read by ' + AContext.Binding.PeerIP); MonitorEnter(Self); try if (Str = 'on') then begin FEnabled := True; FIndex := 0; if (Str = 'off') then FEnabled := False; finally MonitorExit(Self); 37

Beep function TserviceBeep.Beep: Boolean; var BeepHz: Integer; begin Result := False; if (not FEnabled) or (FIndex < 0) then Exit; WriteIoPortByte($61, ReadIoPortByte($61) and $fc); Inc(FIndex); Result := True; if (FIndex >= FParams.Count) then FIndex := 0; with PBeepParam(FParams[FIndex])^ do begin if (Freq <> 0) then begin BeepHz := 1193180 div Freq; WriteIoPortByte($43, $B6); WriteIoPortByte($42, BeepHz and $FF); WriteIoPortByte($42, (BeepHz shr 8) and $FF); WriteIoPortByte($61, ReadIoPortByte($61) or $03); Sleep(Duration); 38

サービスのインストール 起動 作成したサービスは /Install でインストールできます 同様に /Uninstall でアンインストールできます この機能は TServiceApplication が提供しています 39

サービスのインストール 起動 デバッグ中はマニュアルで開始 停止すると良いでしょう 実運用ではバッチファイルなので "net start サービス名 " などとして起動させます 40

17 Th Developer Camp サービスのデモ 41

クライアントの作成 クライアントは以下の動作とします サービスに TIdTCPClient を経由して接続します ボタンを押すとサービスに 'on' または 'off' を送信します 42

クライアント側プログラム procedure TForm1.Button1Click(Sender: TObject); begin if (not tcpclient.connected) then tcpclient.connect; tcpclient.iohandler.write('on'#0); procedure TForm1.Button2Click(Sender: TObject); begin tcpclient.iohandler.write('off'#0); if (tcpclient.connected) then tcpclient.disconnect; 43

17 Th Developer Camp クライアントとの 通信デモ 44

17 Th Developer Camp 2 まとめ 45

まとめ Delphi の提供しているプロジェクトを使えばサービスは簡単に作れます TService がサービスに必要な基本的な機能を提供しているため プログラマはサービスの実際の動作に集中できます サービスは高い権限で動作します 作成したサービスはコマンドラインスイッチ Install, Uninstall でインストール アンインストールできます サービスとの通信は ソケットや名前付きパイプを使います 権限が重要でない場合はソケット 重要である場合は名前付きパイプを使います 46

17 Th Developer Camp Q & A 47