0

このコードを使用してコンボボックスに Active Directory ユーザーを入力していますが、コードが機能する横の「for each」で COM 例外が発生することがあります。

System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry("LDAP://DC=DOMAIN, DC=local");
System.DirectoryServices.DirectorySearcher mySearcher = new System.DirectoryServices.DirectorySearcher(entry);
mySearcher.Filter = "(&(objectClass=user)(objectCategory=person))";

foreach (System.DirectoryServices.SearchResult resEnt in mySearcher.FindAll())
{
   try
   {
       //DirectoryEntry de = new DirectoryEntry(resEnt.GetDirectoryEntry());
       System.DirectoryServices.DirectoryEntry de = resEnt.GetDirectoryEntry();
       comboBox2.Items.Add(de.Properties["GivenName"].Value.ToString() + " " + de.Properties["sn"].Value.ToString() + " " + "[" + de.Properties["sAMAccountName"].Value.ToString() + "]");
   }
   catch (Exception e)
   {
       // MessageBox.Show(e.ToString());
   }
}

これを行う、またはエラーを解決するためのより効率的な方法はありますか?

4

2 に答える 2

4

最初に、結果から取得したいプロパティを検索結果に含めます。これにより、結果.GetDirectoryEntry()ごとに呼び出しを行う必要がなくなります。

using System.DirectoryServices;

DirectoryEntry entry = new DirectoryEntry("LDAP://DC=DOMAIN, DC=local");

DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = "(&(objectClass=user)(objectCategory=person))";

// define the properties you want to be loaded into the search result object
mySearcher.PropertiesToLoad.Add("GivenName");
mySearcher.PropertiesToLoad.Add("samAccountName");
mySearcher.PropertiesToLoad.Add("sn");

foreach (SearchResult resEnt in mySearcher.FindAll())
{
   try
   {
       string givenName = "";
       string samAccountName = "";
       string surName = "";

       // check if you got a value - not all properties have to be filled - 
       // and if they're not filled, they might be "null". 
       if(resEnt.Properties["GivenName"] != null && 
          resEnt.Properties["GivenName"].Count > 0) 
       {
           givenName = resEnt.Properties["GivenName"].Value;
       }

       // samAccountName is a *must* property - it has to be set.
       samAccountName = resEnt.Properties["samAccountName"].Value;

       if(resEnt.Properties["sn"] != null && 
          resEnt.Properties["sn"].Count > 0) 
       {
           surName = resEnt.Properties["sn"].Value;
       }

       comboBox2.Items.Add(givenName + " " + surName + " " + "[" + samAccountName + "]");
   }
   catch (Exception e)
   {
       // MessageBox.Show(e.ToString());
   }
}

2 番目のポイントは、.NET 3.5 以降を使用している場合はPrincipalSearcher、「例によるクエリ」プリンシパルを使用して検索を実行できることです。また、オブジェクトを使用して結果セットを操作するのは非常UserPrincipalに簡単です。GivenNameSurnameUserPrincipal

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for any UserPrincipal 
UserPrincipal qbeUser = new UserPrincipal(ctx);

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// find all matches
foreach(var found in srch.FindAll())
{
    // do whatever here 
    UserPrincipal foundUser = found as UserPrincipal;

    if(foundUser != null)
    {
       comboBox2.Items.Add(foundUser.GivenName + " " + foundUser.Surname + " " + "[" + foundUser.SamAccountName + "]");
    }
}

まだお読みでない場合は、.NET Framework 3.5でディレクトリ セキュリティ プリンシパルを管理するという MSDN の記事を必ずお読みくださいSystem.DirectoryServices.AccountManagement。または、System.DirectoryServices.AccountManagement 名前空間に関する MSDN ドキュメントを参照してください。

もちろん、必要に応じて、作成した「例によるクエリ」ユーザー プリンシパルに他のプロパティを指定することもできます。

  • DisplayName(通常: 名 + スペース + 姓)
  • SAM Account Name- Windows/AD アカウント名
  • User Principal Name- "username@yourcompany.com" スタイル名

の任意のプロパティを指定し、UserPrincipalそれらを の「例によるクエリ」として使用できますPrincipalSearcher

于 2012-09-19T19:43:32.683 に答える
0

foreach ループを try...catch ステートメントの catch ブロック内に配置します。

于 2012-09-19T19:11:07.867 に答える