0

Windowsセッションの変更を監視し、特定のユーザーがログオンした場合にアプリケーションを自動的に起動する必要があるサービスアプリケーションに取り組んでいます。

仕組みは次のとおりです。ユーザープリンシパル名の形式(user@domain.LOCAL)で保存されたWindowsユーザー名のリストを含むファイルがあります。私のサービスはセッションの変更を監視し、それらのユーザーの1人がログオンすると特定のアクションを実行します。

List<string> _UsersList;
 object _sessionCheckLock = new object();
        void OnCheckSession(int nSessionId, bool bIsLoggIn)
        {
            lock(_sessionCheckLock)
            {
                try
                {
                    string sUserName = string.Empty;
                    string sDomain = string.Empty;

                    IntPtr pUserName = IntPtr.Zero;
                    uint nBytesReturned = 0;
                    if (WTSQuerySessionInformation(IntPtr.Zero, (uint)nSessionId, WTS_INFO_CLASS.WTSUserName, out pUserName, out nBytesReturned) && (pUserName != IntPtr.Zero))
                    {
                        sUserName = Marshal.PtrToStringAnsi(pUserName);

                        WTSFreeMemory(pUserName);

                        IntPtr pDomain = IntPtr.Zero;
                        if(WTSQuerySessionInformation(IntPtr.Zero, (uint)nSessionId, WTS_INFO_CLASS.WTSDomainName, out pDomain, out nBytesReturned) && (pDomain != IntPtr.Zero))
                        {
                            sDomain = Marshal.PtrToStringAnsi(pDomain);
                            WTSFreeMemory(pDomain);
                        }
                        else
                        {

                        }

                        if (!string.IsNullOrEmpty(sUserName))
                        {
                          if(!string.IsNullOrEmpty(sDomain)
                          {
                              sUserName += "@" + sDomain;
                          }

                            foreach(string username in _UsersList)
                            {
                               if(string.Compare(sUsername, username, true)==0)
                               {
                                //Do a couple of things
                                return;
                               }
                            }

                        }
                    }
                    else
                    {
                        return;
                    }
                }
                catch (System.Exception ex)
                {

                }
            }
        }

上記のコードは、新しいログオンイベントが発生するたびに呼び出す関数です。_UsersListは、サービスが使用できるすべてのユーザー名を含む文字列のリストです。ここでの問題は、でWTSQuerySessionInformation使用するとWTS_INFO_CLASS.WTSDomainNameドメインのフルネームが返されないため、比較が失敗することです。たとえば、(username@DOMAIN.LOCAL)というユーザー名がユーザーのリストに存在し、ログオンすると、セッションのドメイン名。.LOCAL付録なしで(DOMAIN)のみを返します。リスト内のドメイン名と一致する完全なドメイン名を取得する方法を見つける必要があります。

誰か助けてもらえますか

4

3 に答える 3

2

Cassia.Netを調べてください。これは非常に便利です。

ソースコードをダウンロードできます。これは、サーバーにログオンしているすべてのユーザーを取得する必要があるプロジェクトに使用しました。

cassia.NETWindowsターミナルサービス/リモートデスクトップサービスライブラリ

http://code.google.com/p/cassia/

それが役立つことを願っています

于 2012-11-30T22:43:36.910 に答える
1

WTSDomainNameは、ユーザーがメンバーになっているドメインを示しています。明示的なドキュメントは見つかりませんが、FQDNではなくnetBios名を取得していると思います。これらの値を保持する2つの環境変数USERDNSDOMAINUSERDOMAINを使用できるはずです。

ADSIを使用して、より詳細な検索を行うこともできます。こちらのスレッドをご覧ください

しかし、これはすべて、ユーザーがツリー内の多くの異なるドメインからログインしている、信じられないほど複雑なフォレスト構造を持っていない限り、アプリに変換をハードコーディングする方がはるかに高速です。それらは頻繁に変更されるものではなく、新しいドメインからログインするユーザーもまれであるはずです。

于 2012-11-28T17:51:08.207 に答える
1

レッドサーペント、カッシアは本当に助けになりましたか?私はあなたと同じ問題を抱えていましたが、CassiaはWTSQuerySessionInformationその下で同じ呼び出しを使用しているようで、それでも私は短いドメイン名しか取得していませんでした。

このページでDsGetDcName私が与えた短いドメイン名を使用してFQDNを取得するために使用できる関数への参照を見つけましたWTSQuerySessionInformation。これが私のために働く私の例です:

std::wstring GetSessionDomainName(DWORD sessionId)
{
    std::wstring domainName;
    LPWSTR buffer = NULL;
    DWORD bufferSize = 0;

    if(WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSDomainName, &buffer, &bufferSize))
    {
        PDOMAIN_CONTROLLER_INFOW domainControllerInfo = NULL;
        DWORD retVal = DsGetDcNameW(NULL, buffer, NULL, NULL, DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME, &domainControllerInfo);
        if (retVal == 0)
            domainName = domainControllerInfo->DnsForestName;

        WTSFreeMemory(buffer);
        NetApiBufferFree(domainControllerInfo);
    }

    return domainName;
}
于 2013-05-17T17:29:37.033 に答える