문제

현재 Windows 사용자 계정의 SID를 쉽게 얻을 수있는 방법을 찾고 있습니다. 나는 WMI를 통해 할 수 있다는 것을 알고 있지만 그 길로 가고 싶지는 않습니다.

C#에서 대답 한 모든 사람에게 C ++를 지정하지 않았습니다. :-)

도움이 되었습니까?

해결책

Win32에서 전화하십시오 GetTokenInformation, 토큰 손잡이를 전달합니다 TokenUser 끊임없는. 그것은 채워집니다 token_user 당신을위한 구조. 거기의 요소 중 하나는 사용자의 SID입니다. Blob (Binary)이지만 사용하여 문자열로 바꿀 수 있습니다. ConvertSidToStringsid.

현재 토큰 손잡이를 잡으려면 사용하십시오. openthreadtoken 또는 OpenProcessToken.

ATL을 선호하는 경우에는 있습니다 caccesstoken 모든 종류의 흥미로운 것들이 있습니다.

.net은 다음과 같습니다 스레드 .CurrentPrinciple iprincipal 참조를 반환하는 속성. SID를 얻을 수 있습니다.

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

또한 .NET에서는 WindowsIndity.GetCurrent ()를 사용할 수 있으며 현재 사용자 ID를 반환합니다.

WindowsIdentity identity = WindowsIdentity.GetCurrent();
if (identity != null)
    Console.WriteLine(identity.User);

다른 팁

이것은 필요한 것을 제공해야합니다.

System.security.principal 사용;

...

var sid = windowsidentity.getCurrent (). 사용자;

Windowsidentity의 사용자 속성은 SID를 반환합니다. MSDN 문서

ATL::CAccessToken accessToken;
ATL::CSid currentUserSid;
if (accessToken.GetProcessToken(TOKEN_READ | TOKEN_QUERY) &&
    accessToken.GetUser(&currentUserSid))
    return currentUserSid.Sid();

CodeProject 시도 할 수있는 몇 가지 방법이 있습니다 ... 솔루션을 원하는 언어를 언급하지 않았습니다.

배치 파일을 통해 액세스하려면 psgetsid로 볼 수 있습니다. sysinternals. SIDS를 이름으로 변환하고 그 반대도 마찬가지입니다.

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;");

SID를 얻는 또 다른 방법을 찾았습니다.

System.Security.Principal.WindowsIdentity id = System.Security.Principal.WindowsIdentity.GetCurrent();
string sid = id.User.AccountDomainSid.ToString();

그리고 기본 코드 :

function GetCurrentUserSid: string;

    hAccessToken: THandle;
    userToken: PTokenUser;
    dwInfoBufferSize: DWORD;
    dw: DWORD;

    if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, ref hAccessToken) then
        dw <- GetLastError;
        if dw <> ERROR_NO_TOKEN then
            RaiseLastOSError(dw);

        if not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, ref hAccessToken) then
            RaiseLastOSError;
    try
        userToken <- GetMemory(1024);
        try
            if not GetTokenInformation(hAccessToken, TokenUser, userToken, 1024, ref dwInfoBufferSize) then
                RaiseLastOSError;
            Result <- SidToString(userToken.User.Sid);
        finally
            FreeMemory(userToken);
    finally
        CloseHandle(hAccessToken);

원하는 언어를 지정하지 않았습니다. 그러나 C#에 올랐다면이 기사는 WMI 방법과 Win32 API를 사용하는 더 빠른 (더 많은 장황한) 방법을 제공합니다.

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

WMI 또는 Win32 API를 사용하지 않고이 작업을 수행하는 또 다른 방법이 있다고 생각하지 않습니다.

이것은 내가 믿는 모든 것 중 가장 짧습니다.

UserPrincipal.Current.Sid;

.NET> = 3.5로 사용할 수 있습니다

이 질문은 다음과 같이 태그됩니다 c++ 그리고 나는 대답합니다 c++ 언어이므로 사용하는 것이 좋습니다 WMI 도구 :

그래서 WMI 명령 powershell, 벨로우 명령은 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++ Bellow (이 예에서는 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();

이 예제는 제대로 작동합니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top