31

現在の Windows ユーザー アカウントの SID を取得する簡単な方法を探しています。WMI を介して実行できることはわかっていますが、そのルートには行きたくありません。

C++ であると指定しなかったために C# で回答したすべての人に謝罪します。:-)

4

11 に答える 11

52

Win32 では、GetTokenInformationを呼び出して、トークン ハンドルとTokenUser定数を渡します。TOKEN_USER構造が埋められます。そこにある要素の 1 つは、ユーザーの SID です。これは BLOB (バイナリ) ですが、ConvertSidToStringSidを使用して文字列に変換できます。

現在のトークン ハンドルを取得するには、OpenThreadTokenまたはOpenProcessTokenを使用します。

ATL の方が好きな場合は、CAccessTokenクラスがあり、あらゆる種類の興味深いものが含まれています。

.NET には、IPrincipal 参照を返すThread.CurrentPrincipleプロパティがあります。SID を取得できます。

IPrincipal principal = Thread.CurrentPrincipal;
WindowsIdentity identity = principal.Identity as WindowsIdentity;
if (identity != null)
    Console.WriteLine(identity.User);

また、.NET では、現在のユーザー ID を返す WindowsIdentity.GetCurrent() を使用できます。

WindowsIdentity identity = WindowsIdentity.GetCurrent();
if (identity != null)
    Console.WriteLine(identity.User);
于 2008-10-30T18:37:35.637 に答える
10
ATL::CAccessToken accessToken;
ATL::CSid currentUserSid;
if (accessToken.GetProcessToken(TOKEN_READ | TOKEN_QUERY) &&
    accessToken.GetUser(&currentUserSid))
    return currentUserSid.Sid();
于 2012-11-13T06:07:38.480 に答える
7

これにより、必要なものが得られます。

System.Security.Principal の使用;

...

var sid = WindowsIdentity.GetCurrent().User;

WindowsIdentity の User プロパティは、 MSDN Docsごとに SID を返します。

于 2008-10-30T18:37:01.287 に答える
3

CodeProjectには、試すことができるいくつかの異なる方法があります...ソリューションが必要な言語については言及していません。

バッチ ファイルなどを介してアクセスする場合は、 Sysinternalsの PsGetSid として参照できます。SID を名前に、またはその逆に変換します。

于 2008-10-30T18:31:50.937 に答える
2

C# では、次のいずれかを使用できます。

using Microsoft.Win32.Security;

...

string username = Environment.UserName + "@" + Environment.GetEnvironmentVariable("USERDNSDOMAIN");

Sid sidUser = new Sid (username);

または...

using System.Security.AccessControl;

using System.Security.Principal;

...

WindowsIdentity m_Self = WindowsIdentity.GetCurrent();

SecurityIdentifier m_SID = m_Self.Owner;");

于 2008-10-30T18:53:43.403 に答える
2

SID を取得する別の方法を見つけました。

System.Security.Principal.WindowsIdentity id = System.Security.Principal.WindowsIdentity.GetCurrent();
string sid = id.User.AccountDomainSid.ToString();
于 2012-01-13T12:26:27.530 に答える
1

この質問は としてタグ付けされていc++ます And I answer in c++language, So I recommend use of WMI tool :

したがって、 のWMIコマンドとして、次のコマンドでuserpowershellを取得します。SIDsystem-pc1

Get-WmiObject win32_useraccount -Filter "name = 'system-pc1'" | Select-Object sid

usernameまず、以下を使用して最新の状態にする必要がありますcode

char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);

WQLこれで、言語を試して、次のようにこのクエリを実行できますc++(この例ではsystem-pc1、クエリでユーザー名を使用しましたWQL_WIN32_USERACCOUNT_QUERY:

#define                 NETWORK_RESOURCE                    "root\\CIMV2"
#define                 WQL_LANGUAGE                        "WQL"
#define                 WQL_WIN32_USERACCOUNT_QUERY         "SELECT * FROM Win32_Useraccount where name='system-pc1'"
#define                 WQL_SID                             "SID"

IWbemLocator            *pLoc = 0;              // Obtain initial locator to WMI to a particular host computer
IWbemServices           *pSvc = 0;              // To use of connection that created with CoCreateInstance()
ULONG                   uReturn = 0;
HRESULT                 hResult = S_OK;         // Result when we initializing
IWbemClassObject        *pClsObject = NULL;     // A class for handle IEnumWbemClassObject objects
IEnumWbemClassObject    *pEnumerator = NULL;    // To enumerate objects
VARIANT                 vtSID = { 0 };          // OS name property

// Initialize COM library
hResult = CoInitializeEx(0, COINIT_MULTITHREADED);
if (SUCCEEDED(hResult))
{
    // Initialize security
    hResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
    if (SUCCEEDED(hResult))
    {
        // Create only one object on the local system
        hResult = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
            IID_IWbemLocator, (LPVOID*)&pLoc);

        if (SUCCEEDED(hResult))
        {
            // Connect to specific host system namespace
            hResult = pLoc->ConnectServer(TEXT(NETWORK_RESOURCE), NULL, NULL,
                0, NULL, 0, 0, &pSvc);
            if (SUCCEEDED(hResult))
            {
                /* Set the IWbemServices proxy
                * So the impersonation of the user will be occurred */
                hResult = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
                    NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE,
                    NULL, EOAC_NONE);
                if (SUCCEEDED(hResult))
                {
                    /* Use the IWbemServices pointer to make requests of WMI
                    * For example, query for user account */
                    hResult = pSvc->ExecQuery(TEXT(WQL_LANGUAGE), TEXT(WQL_WIN32_USERACCOUNT_QUERY),
                        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
                    if (SUCCEEDED(hResult))
                    {
                        // Go to get the next object from IEnumWbemClassObject
                        pEnumerator->Next(WBEM_INFINITE, 1, &pClsObject, &uReturn);
                        if (uReturn != 0)
                        {
                            // Get the value of the "sid, ..." property
                            pClsObject->Get(TEXT(WQL_SID), 0, &vtSID, 0, 0);
                            VariantClear(&vtSID);

                            // Print SID
                            wcout << vtSID.bstrVal;

                            pClsObject->Release();
                            pClsObject = NULL;
                        }
                    }
                }
            }
        }
    }

    // Cleanup
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    // Uninitialize COM library
    CoUninitialize();

この例は正しく機能します。

于 2018-11-12T06:28:53.113 に答える
0

必要な言語を指定しませんでした。しかし、C# に慣れている場合は、この記事で WMI の方法と、Win32 API を利用したより高速な (より冗長な) メソッドの両方を紹介します。

http://www.codeproject.com/KB/cs/processownersid.aspx

現在のところ、WMI や Win32 API を使用せずにこれを行う別の方法はないと思います。

于 2008-10-30T18:34:47.157 に答える
0

これは私が信じている中で最も短いものです。

UserPrincipal.Current.Sid;

.net >= 3.5 で利用可能

于 2012-10-23T14:33:28.377 に答える