マイナーでもいいよね??

殆どVB系、でも .NET じゃない VB は知らないよん

目次

Blog 利用状況

書庫

日記カテゴリ

サンプルアプリの画面側 ~グループのリスト~

グループのリストもユーザのリストと同じでローカル用も考慮して実装します。

まずは実行時の画面。左がドメインログオン時で右がローカルログオン時。(クリックすると新しいウィンドウで拡大図が表示されます。)

グループリスト ローカルグループリスト

実装はこんな感じ。

プライベートフィールド

Private ReadOnly groups As IEnumerable(Of IGroup)   'グループのリスト
'プライマリグループのメンバ格納用(グループのPrimaryGroupToken, メンバのパスとオブジェクトの種類のリスト)
Private ReadOnly primaryGroupMembers As Dictionary(Of Integer, Dictionary(Of String, CategoryType))
Private ReadOnly groupBindingSource As BindingSource


コンストラクタ

Public Sub New()
  ' この呼び出しはデザイナーで必要です。
  InitializeComponent()
  ' InitializeComponent() 呼び出しの後で初期化を追加します。

  groups = DirectoryAccess.GetGroups()    'グループのリストを取得
  If DirectoryAccess.IsLogonDomain Then    'ドメインにログオンしている時
    Dim domainGroups As New List(Of DomainGroup)
    For Each group As DomainGroup In groups
      domainGroups.Add(group)
    Next

    groupBindingSource = Me.DomainGroupBindingSource
    groupBindingSource.DataSource = domainGroups
    Me.pnl_local.Visible = False
  Else    'ドメインにログオンしていない時
    Dim localGroups As New List(Of LocalGroup)
    For Each group As LocalGroup In groups
      localGroups.Add(group)
    Next

    groupBindingSource = Me.LocalGroupBindingSource
    groupBindingSource.DataSource = localGroups
    Me.pnl_domain.Visible = False
    Me.lbox_group.Height -= 96
    Me.Height -= 166
  End If
  Me
.DescriptionTextBox.DataBindings.Add("Text", groupBindingSource, "Description")
  Me.lbox_group.Items.AddRange(groups.ToArray())    'グループのリストボックスにグループを追加

  primaryGroupMembers = New Dictionary(Of Integer, Dictionary(Of String, CategoryType))()
  Me.lbl_count.Text = String.Format("{0} 個のオブジェクト", groupBindingSource.Count)
  Me.lbox_group.SelectedIndex = groupBindingSource.Position
  Call ShowRelatingInfo()   '関連情報を表示
End Sub


イベントハンドラ

Private Sub lbox_group_SelectedIndexChanged(
  sender As Object, e As EventArgs) Handles lbox_group.SelectedIndexChanged

  '選択されている項目を選択してもイベントが発生する
  If groupBindingSource.Position = Me.lbox_group.SelectedIndex Then
    Return
  End If

  groupBindingSource.Position = Me.lbox_group.SelectedIndex
  Call ShowRelatingInfo()   '関連情報を表示
End Sub


プライベートメソッド

Private Sub ShowRelatingInfo()    '関連情報を表示
  Dim group = DirectCast(groupBindingSource.Current, IGroup)    '選択されたグループ
  If DirectoryAccess.IsLogonDomain Then    'ドメインにログオンしている時
    Call ShowDomainMembers(group.Native)    'ドメイングループのメンバを表示
    Call ShowBelongGroups(group.Native)    '所属するグループを表示
  Else    'ドメインにログオンしていない時
    Call ShowLocalMembers(group.Native)   'ローカルグループのメンバを表示
  End If
End Sub

Private Sub ShowDomainMembers(group As IADsGroup)    'ドメイングループのメンバを表示
  Dim subItem(1) As String    '名前と所属パスの配列
  Dim objectType As CategoryType    'ディレクトリ オブジェクトの種類

  Me.lv_member.Items.Clear()
  For Each member As IADs In group.Members()
    subItem(0) = DirectoryAccess.PathToCn(member.Name)    '名前を取得
    subItem(1) = DirectoryAccess.GetBelongPath(member)    '所属パスを取得
    [Enum].TryParse(Of CategoryType)(member.Class, True, objectType)
    Call AddListViewItem(Me.lv_member, subItem, True, objectType)   'リストビューにアイテムを追加
  Next
  Call
AddPrimaryGroupMembers()   'プライマリグループになっているメンバを追加
End Sub

Private Sub AddListViewItem(lView As ListView, subItem() As String, showImage As Boolean,
  Optional objectCategory As CategoryType = CategoryType.User)    'リストビューにアイテムを追加

  Dim listItem As ListViewItem
  If showImage Then   'イメージを表示する時
    listItem = New ListViewItem(subItem, objectCategory)
  Else    'イメージを表示しない時
    listItem = New ListViewItem(subItem)
  End If

  listItem.SubItems.AddRange(subItem)
  lView.Items.Add(listItem)
End Sub

Private Sub AddPrimaryGroupMembers()    'プライマリグループになっているメンバを追加
  Dim group = DirectoryAccess.GroupTokens.ElementAt(groupBindingSource.Position)  '選択したグループ
  'プライマリグループのメンバ(パスとオブジェクトの種類のリスト)
  Dim primaryMembers As Dictionary(Of String, CategoryType) = Nothing

  If primaryGroupMembers.TryGetValue(group.Key, primaryMembers) Then    '格納済の時
    If primaryMembers.Count = 0 Then
      Return
    End If
  Else
    '未格納の時
    ‘指定した PrimaryGroupToken を持つグループをプライマリグループとしているメンバの DirectoryEntry のリスト
    Dim primaryMemberEntries = DirectoryAccess.GetPrimaryGroupMemberEntries(group.Key)
    primaryMembers = New Dictionary(Of String, CategoryType)(primaryMemberEntries.Count)
    primaryGroupMembers.Add(group.Key, primaryMembers)
    If primaryMemberEntries.Count = 0 Then
      Return
    End If

    For Each user In primaryMemberEntries
      primaryMembers.Add(user.Path,
        DirectCast([Enum].Parse(GetType(CategoryType), user.SchemaClassName, True), CategoryType))
      user.Close()
    Next
  End If

  Dim subItem(1) As String    '名前と所属パスの配列
  For Each member In primaryMembers
    subItem(0) = DirectoryAccess.PathToCn(member.Key)   '名前を取得
    subItem(1) = DirectoryAccess.GetBelongPath(member.Key)    '所属パスを取得
    Call AddListViewItem(Me.lv_member, subItem, True, member.Value)   'リストビューにアイテムを追加
  Next
End Sub

Private Sub ShowBelongGroups(group As IADsGroup)    '所属するグループを表示
  Dim groupObjects As Object    '所属するグループ
  Me.lv_group.Items.Clear()

  Try
    groupObjects = group.GetEx("memberOf")
  Catch   '所属するグループがない
   Return
  End Try

  Dim subItem(1) As String      '名前と所属パスの配列
  For Each groupObject As String In DirectCast(groupObjects, IEnumerable)
    subItem(0) = DirectoryAccess.PathToCn(groupObject)    '名前を取得
    subItem(1) = DirectoryAccess.GetBelongPath(groupObject)   '所属パスを取得
    Call AddListViewItem(Me.lv_group, subItem, False)    'リストビューにアイテムを追加
  Next
End Sub

Private Sub ShowLocalMembers(group As IADsGroup)    'ローカルグループのメンバを表示
  Dim memberName As String
  Me.lbox_member.Items.Clear()

  For Each member As IADs In group.Members()
    memberName = GetLocalMemberName(member)   'ローカルのメンバ名を取得
    Me.lbox_member.Items.Add(memberName)
  Next
End Sub

Private Function GetLocalMemberName(member As IADs) As String    'ローカルのメンバ名を取得
  If TypeOf member Is IADsUser Then   'ユーザの時
    Return member.ADsPath.Substring(member.ADsPath.LastIndexOf("/"c) + 1)
  Else    'グループの時
    Return member.ADsPath.Substring(8).Replace("/"c, "\"c)
  End If
End Function


デザイナファイルの Dispose メソッド内の components.Dispose() の下に次のコードを追記

DirectoryAccess.DisposeItems(groups)


ShowBelongGroups メソッドの Try ブロック内で GetEx メソッドを呼んでます。

このメソッドは IADs インターフェイスで定義されてます。似たようなメソッドに Get メソッドがあります。

Get メソッドも GetEx メソッドも指定した名前のプロパティ値を取得します。戻り値の型は Object 型ですが次の違いがあります。

Get メソッドは、値が 1つしかないプロパティの場合は単一の値を返し、値が複数あるプロパティの場合は配列を返します。

GetEx メソッドは値が 1つしかないプロパティでも値が複数あるプロパティでも配列を返します。

値が複数あるプロパティには次のようなものがあります。

・ユーザ、グループ、コンピュータが所属するグループ(上記 memberOf)
・グループのメンバ(member)
・プリンタの利用可能な用紙(printMediaSupported)
・共有フォルダのキーワード(keywords)

値が 1つしかないと判ってるプロパティの取得なら Get メソッドを呼べばループ処理は要らないですね。

 

おまけ

Office 製品で Visual Basic Editor を表示する時は Alt + F11。

投稿日時 : 2011年7月21日 22:36

コメントを追加

# サンプルアプリの画面側、一部変更 2011/07/26 0:36 マイナーでもいいよね??

サンプルアプリの画面側、一部変更

タイトル
名前
URL
コメント