ワークステーションロック?
         Ahf(小尾 智之)
自己紹介
VB と SQL Server が主戦場
 主に流通系・・・に限らず色々
 実装・設計・サポート・管理とちょっと幅広
インディープロレス・クマ(クマー含む)好き
 もっふりしたもの全般好き
@IT エンジニアライフで色々書いてます
 月一回がここ最近の限度・・・
ワークステーションロック?
 [Windows] + [L] や [Ctrl] + [Alt] + [Del] で
  選ぶとかで行えるデスクトップのロック
 ロックは一定時間で自動的になる(サーバー)
 不正利用防止とかで大体適用されている…ハズ
監視系アプリへの要望として


 「ステーションロックを検知してログに残せ」
  という要望もそれなりにある
 市販品は予算の都合上で無理な事も多々ある
 諦めて作らざるを得ない!
ロックの検知
 以前は WMI とか利用してやっていたそうで
  Scripting Guy!の2004年あたりを応用
 今は System.ServiceProcess.ServiceBase クラス
 SessionChange イベントにてトラップできる
 サービス AP なのでバックグラウンド動作する
  だから監視系にも適切




      Windows XP までならば!
セッション0・・・
 Vista 以降のクライアント OS では
  サービスはセッション0で動作するので
  デスクトップのロックは検知できるわけがない
 サーバー系 OS はマルチセッションが当然だから
  どのみちちゃんと検知はできない
 設計としてダメ




 ユーザーセッションでロックを検知して
  ログを記載する設計でないと無理
SystemEvent 静的クラス
           Microsoft.Win32.SystemEvent 静的クラスにて
            システムイベントの検知方法が提供されている
         イベント名                                 説明
DisplaySettingsChanged    ユーザーが表示設定を変更すると発生します。
DisplaySettingsChanging   表示設定が変更されているときに発生します。
EventsThreadShutdown      システム イベントを待機するスレッドが終了する前に発生します。
InstalledFontsChanged     ユーザーがシステム フォントを追加するか、またはシステム フォントを削除すると発生します。

LowMemory                 互換性のために残されています。システムで使用可能な RAM が不足すると発生します。

PaletteChanged            ユーザーが、別のパレットを使用するアプリケーションに切り替えると発生します。
PowerModeChanged          ユーザーがシステムを中断または再開すると発生します。
SessionEnded              ユーザーがシステムからログオフするか、システムをシャットダウンすると発生します。
                          ユーザーがシステムからログオフしようとした場合、またはシステムをシャットダウンしよう
SessionEnding
                          とした場合に発生します。
SessionSwitch             現在ログインしているユーザーが変更された場合に発生します。
TimeChanged               ユーザーがシステム時間を変更すると発生します。
TimerElapsed              ウィンドウ タイマー間隔が経過したときに発生します。
UserPreferenceChanged     ユーザー設定が変更されると発生します。
UserPreferenceChanging    ユーザー設定を変更しているときに発生します。

                            http://msdn.microsoft.com/ja-jp/library/z1bwe429(v=VS.100).aspx
ロックの検知
         SessionSwitch イベントでこのようにトラップ
Private Sub SessionSwitch(ByVal sender As Object, ByVal e As SessionSwitchEventArgs)
     Try
        Select Case e.Reason
          Case SessionSwitchReason.ConsoleConnect
          Case SessionSwitchReason.ConsoleDisconnect

         Case SessionSwitchReason.RemoteConnect
         Case SessionSwitchReason.RemoteDisconnect

         Case SessionSwitchReason.SessionLock
           Debug.WriteLine(“監禁されたでござる")
         Case SessionSwitchReason.SessionUnlock
           Debug.WriteLine(“恩赦でござる")

         Case SessionSwitchReason.SessionLogon
         Case SessionSwitchReason.SessionLogoff

      End Select
    Catch ex As Exception                    このようなメソッドを
                                             SystenEvent.SessionSwitch イベントに
   End Try                                   AddHandler 等で関連付ければOK
 End Sub
後はログとしての記録
   セッションロックはそれぞれのユーザーセッションで
    検知しなくてはいけない
   ログとしての記録はユーザーセッションである必要はない




  ログ記録はサービスとして動作させる!



プログラム間通信は WCF の名前付きパイプが楽
WCF セルフホスト
Dim localServiceAddress As Uri() = {New Uri(“net.pipe://localhost/サービスアドレス")}
Dim svType As Type = GetType([サービスクラス])

Dim svInst As New ServiceHost(svType, localServiceAddress)

Dim nmPipeBnd As Binding = New NetNamedPipeBinding(NetNamedPipeSecurityMode.None)

nmPipeBnd.Namespace = BINDING_NAMESPACE

Dim procesMetadata As New ServiceMetadataBehavior
svInst.AddServiceEndpoint(GetType([サービスインターフェース]), nmPipeBnd, String.Empty)
svInst.Description.Behaviors.Add(procesMetadata)
                                                             セルフホスト側( 9行)
svInst.Open()


Dim namedPipe As Binding = New NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
Dim localAddress As New EndpointAddress(“net.pipe://localhost/サービスアドレス")

Dim chFact As New ChannelFactory(Of [サービスインターフェース])(namedPipe, localAddress)

chFact.Open()                                                クライアント側( 5行)
Dim cProxy As [サービスインターフェース] = chFact.CreateChannel
最終的な構成
 サービスを分離させることでスッキリ
 最後のひと手間はクライアント側からの
  呼び出しをキューなどを利用して
  非同期に処理するようにする

    MessageQue




     これでレスポンス的にも
     いい塩梅です
ご清聴ありがとうございました

Lt 110205

  • 1.
  • 2.
    自己紹介 VB と SQLServer が主戦場 主に流通系・・・に限らず色々 実装・設計・サポート・管理とちょっと幅広 インディープロレス・クマ(クマー含む)好き もっふりしたもの全般好き @IT エンジニアライフで色々書いてます 月一回がここ最近の限度・・・
  • 3.
    ワークステーションロック?  [Windows] +[L] や [Ctrl] + [Alt] + [Del] で 選ぶとかで行えるデスクトップのロック  ロックは一定時間で自動的になる(サーバー)  不正利用防止とかで大体適用されている…ハズ
  • 4.
    監視系アプリへの要望として  「ステーションロックを検知してログに残せ」 という要望もそれなりにある  市販品は予算の都合上で無理な事も多々ある  諦めて作らざるを得ない!
  • 5.
    ロックの検知  以前は WMIとか利用してやっていたそうで  Scripting Guy!の2004年あたりを応用  今は System.ServiceProcess.ServiceBase クラス  SessionChange イベントにてトラップできる  サービス AP なのでバックグラウンド動作する だから監視系にも適切 Windows XP までならば!
  • 6.
    セッション0・・・  Vista 以降のクライアントOS では サービスはセッション0で動作するので デスクトップのロックは検知できるわけがない  サーバー系 OS はマルチセッションが当然だから どのみちちゃんと検知はできない  設計としてダメ  ユーザーセッションでロックを検知して ログを記載する設計でないと無理
  • 7.
    SystemEvent 静的クラス  Microsoft.Win32.SystemEvent 静的クラスにて システムイベントの検知方法が提供されている イベント名 説明 DisplaySettingsChanged ユーザーが表示設定を変更すると発生します。 DisplaySettingsChanging 表示設定が変更されているときに発生します。 EventsThreadShutdown システム イベントを待機するスレッドが終了する前に発生します。 InstalledFontsChanged ユーザーがシステム フォントを追加するか、またはシステム フォントを削除すると発生します。 LowMemory 互換性のために残されています。システムで使用可能な RAM が不足すると発生します。 PaletteChanged ユーザーが、別のパレットを使用するアプリケーションに切り替えると発生します。 PowerModeChanged ユーザーがシステムを中断または再開すると発生します。 SessionEnded ユーザーがシステムからログオフするか、システムをシャットダウンすると発生します。 ユーザーがシステムからログオフしようとした場合、またはシステムをシャットダウンしよう SessionEnding とした場合に発生します。 SessionSwitch 現在ログインしているユーザーが変更された場合に発生します。 TimeChanged ユーザーがシステム時間を変更すると発生します。 TimerElapsed ウィンドウ タイマー間隔が経過したときに発生します。 UserPreferenceChanged ユーザー設定が変更されると発生します。 UserPreferenceChanging ユーザー設定を変更しているときに発生します。 http://msdn.microsoft.com/ja-jp/library/z1bwe429(v=VS.100).aspx
  • 8.
    ロックの検知  SessionSwitch イベントでこのようにトラップ Private Sub SessionSwitch(ByVal sender As Object, ByVal e As SessionSwitchEventArgs) Try Select Case e.Reason Case SessionSwitchReason.ConsoleConnect Case SessionSwitchReason.ConsoleDisconnect Case SessionSwitchReason.RemoteConnect Case SessionSwitchReason.RemoteDisconnect Case SessionSwitchReason.SessionLock Debug.WriteLine(“監禁されたでござる") Case SessionSwitchReason.SessionUnlock Debug.WriteLine(“恩赦でござる") Case SessionSwitchReason.SessionLogon Case SessionSwitchReason.SessionLogoff End Select Catch ex As Exception このようなメソッドを SystenEvent.SessionSwitch イベントに End Try AddHandler 等で関連付ければOK End Sub
  • 9.
    後はログとしての記録 セッションロックはそれぞれのユーザーセッションで 検知しなくてはいけない  ログとしての記録はユーザーセッションである必要はない ログ記録はサービスとして動作させる! プログラム間通信は WCF の名前付きパイプが楽
  • 10.
    WCF セルフホスト Dim localServiceAddressAs Uri() = {New Uri(“net.pipe://localhost/サービスアドレス")} Dim svType As Type = GetType([サービスクラス]) Dim svInst As New ServiceHost(svType, localServiceAddress) Dim nmPipeBnd As Binding = New NetNamedPipeBinding(NetNamedPipeSecurityMode.None) nmPipeBnd.Namespace = BINDING_NAMESPACE Dim procesMetadata As New ServiceMetadataBehavior svInst.AddServiceEndpoint(GetType([サービスインターフェース]), nmPipeBnd, String.Empty) svInst.Description.Behaviors.Add(procesMetadata) セルフホスト側( 9行) svInst.Open() Dim namedPipe As Binding = New NetNamedPipeBinding(NetNamedPipeSecurityMode.None) Dim localAddress As New EndpointAddress(“net.pipe://localhost/サービスアドレス") Dim chFact As New ChannelFactory(Of [サービスインターフェース])(namedPipe, localAddress) chFact.Open() クライアント側( 5行) Dim cProxy As [サービスインターフェース] = chFact.CreateChannel
  • 11.
    最終的な構成  サービスを分離させることでスッキリ  最後のひと手間はクライアント側からの 呼び出しをキューなどを利用して 非同期に処理するようにする MessageQue これでレスポンス的にも いい塩梅です
  • 12.