none
ドメインユーザーの「フルネーム」取得の方法 RRS feed

  • 質問

  • はじめて投稿いたします。よろしくお願いいたします。

    NTドメイン環境にあります。ログオンのときとは別に、フルネームというのがありますよね。

    XPでスタートメニューを開いたときにメニュー上部に表示されるあの名前です。

    System.Windows.Forms.SystemInformation.UserName

    では、ログオンのときに入力する名前しか取得できませんでした。

    具体的な用途としては、舞黒 祖父人さんがログオンするときは、「s-maikuro」と入力して

    いるとします。けれども、アプリケーションで「s-maikuro」ではなく、「舞黒 祖父人」と

    表示させたいのです。

    フルネームを読み出す方法がわからないので、どうかお教えいただきとう願います。

    2006年7月29日 9:01

回答

  • System.DirectoryServices を参照設定して下記のコードを実行してください。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.DirectoryServices;

    namespace LogonUser
    {
        public partial class Form1 : Form
        {
            private void button1_Click(object sender, EventArgs e)
            {
                string userName = System.Windows.Forms.SystemInformation.UserName;
                string ldap = "LDAP://DC=XXX,DC=XXX,DC=XXXX,DC=XXXX";
                DirectoryEntry de = new DirectoryEntry(ldap);
                DirectorySearcher ds = new DirectorySearcher(de);
                ds.Filter = String.Format("(&(objectCategory=person)(objectClass=user)(samaccountname={0}))", userName); ;
                SearchResult sr = ds.FindOne();
                string displayName = "";
                if (sr != null)
                {
                    displayName = sr.Properties["displayname"][0].ToString();
                }
                de.Close();
                MessageBox.Show(displayName);
            }
            public Form1()
            {
                InitializeComponent();
            }

        }
    }

    2006年7月31日 2:10
  • 悲しいですな。。。

    して、解決してます?
    COM の Active DS Type Library を参照設定して、下記のコードを試してもらえます?
    [DomainName] は NT ドメイン名、[UserName] はユーザ名です。
    # Active DS Type Library はなくてもいけるんですが、めんどくさいので。。。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.DirectoryServices;
    using ActiveDs;
    namespace WinNTTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                string winnt = "WinNT://[DomainName]/[UserName],User";
                DirectoryEntry de = new DirectoryEntry(winnt);
                IADsUser user = (IADsUser)de.NativeObject;
                Console.WriteLine(user.FullName);
            }
        }
    }

    2006年8月4日 12:43

すべての返信

  • System.DirectoryServices を参照設定して下記のコードを実行してください。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.DirectoryServices;

    namespace LogonUser
    {
        public partial class Form1 : Form
        {
            private void button1_Click(object sender, EventArgs e)
            {
                string userName = System.Windows.Forms.SystemInformation.UserName;
                string ldap = "LDAP://DC=XXX,DC=XXX,DC=XXXX,DC=XXXX";
                DirectoryEntry de = new DirectoryEntry(ldap);
                DirectorySearcher ds = new DirectorySearcher(de);
                ds.Filter = String.Format("(&(objectCategory=person)(objectClass=user)(samaccountname={0}))", userName); ;
                SearchResult sr = ds.FindOne();
                string displayName = "";
                if (sr != null)
                {
                    displayName = sr.Properties["displayname"][0].ToString();
                }
                de.Close();
                MessageBox.Show(displayName);
            }
            public Form1()
            {
                InitializeComponent();
            }

        }
    }

    2006年7月31日 2:10
  • ご返答ありがとうございます。けれども、例外が出てしまいました。

    「指定されたドメインがないか、またはアクセスできません。」

    いろいろと調べて、「WinNT://ドメイン名/」とか、「LDAP://CN=PDC名」とかやってみたのですが、できませんでした。

    指定の仕方が悪いのでしょうか。

    2006年8月2日 3:22
  • ドメインの FQDN が hoge.local だった場合、LDAP 文字列は ldap://DC=hoge,DC=local となります。
    こちらはドメインに参加しているコンピュータからの方法で、ドメインに参加していない場合は ldap://dc-name.hoge.local/DC=hoge,DC=local とドメインコントローラの FQDN を指定します。
    ドメインに参加していない場合は、接続するために認証が必要になりますので DirectoryEntry(ldap, "DomainName\\UserName", "Password") としてください。
    ユーザ名の指定ですが、プリンシパル名(username@domainname)でも可能です。
    接続時にセキュリティレベルを上げたい場合は、DirectoryEntry の 4 番目の引数に AuthenticationTypes を指定するようにしてください。

    あとは MSDN のヘルプや私のブログ「[.NET]ActiveDirectory の Sercurity Group の確認方法 」あたりを参照してください。

    2006年8月2日 5:46
  • FQDNやLDAPなど、ActiveDirectory的な用語が使われていますが、ADなしのまったくのNTドメインです。だから、うまくいかないのでしょうか。

    2006年8月3日 2:24
  • Windows NT 4.0 ドメイン!!!

    そのときは WinNT:// でやってください。
    で、やり方は根本的に変わると思いますので、ADSI のサンプルを見てください。

    # Windows NT 4.0 はサポート切れなので早く移行を検討してくださいね。

    2006年8月3日 23:59
  • そうなんです。移行したくてたまりません。そして、後ろを振り返らなければいけない、将来的に使えなくなるレガシーなこの感じが、とても憂鬱です。けれども、これが現実です。

    前任者のコードはハードコーディングバリバリ。PDCの名前がサーバーの機種名。もちろん変更もできない。けれども、ユーザー企業のたった一人の情報システム屋(設計者&開発者&管理者&工事者)の言い分は、「今のままでも使えているじゃないか」という一言で、粉砕されてしまうのです。

    Visual Studio2005は、何とか買ってもらったものの、社内中のOfficeはすべて2000なので、VSTOも使えない。NTドメインであるがために、40もあるクライアントのパッチ当ては、一人でやらねばならない…… 誰もわかってくれない……  愚痴になってすみません……

    2006年8月4日 0:20
  • 悲しいですな。。。

    して、解決してます?
    COM の Active DS Type Library を参照設定して、下記のコードを試してもらえます?
    [DomainName] は NT ドメイン名、[UserName] はユーザ名です。
    # Active DS Type Library はなくてもいけるんですが、めんどくさいので。。。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.DirectoryServices;
    using ActiveDs;
    namespace WinNTTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                string winnt = "WinNT://[DomainName]/[UserName],User";
                DirectoryEntry de = new DirectoryEntry(winnt);
                IADsUser user = (IADsUser)de.NativeObject;
                Console.WriteLine(user.FullName);
            }
        }
    }

    2006年8月4日 12:43
  • レスが遅くなり、すみません。

    解決したのは、上記と全く同様のコードでした。ありがとうございました

    で、COMライブラリを読み込むのは、本当は、マネージとしてあまり推奨されないのでしょうか?

    2006年8月6日 23:13
  • 何があるかわからないので、どちらかというと使わないに越したことはないというのが私の見解です。

    正しく開放することが前提になり、using ステートメントが使えない(Dispose の実装がない)場合は、オブジェクトの参照を明示的に null にするなど対策をしておいたほうがいいと思います。
    GC を .NET Framework まかせにすると、使用メモリがリークしているように見えたりしますので、System.GC.Collect を明示的に実行してもよいかもしれません。

    2006年8月6日 23:56
  • >正しく開放することが前提になり、using ステートメントが使えない(Dispose の実装がない)場合は、オブジェクトの参照を明示的に null にするなど対策をしておいたほうがいいと思います。
    >GC を .NET Framework まかせにすると、使用メモリがリークしているように見えたりしますので、System.GC.Collect を明示的に実行してもよいかもしれません。

    Marshal.ReleaseComObjectを使うのはどうでしょう?

    (COM参照した場合に、IDisposableで勝手に実装してくれたらいいのに)

     

    2006年11月14日 0:07