Frage

Ich bin für eine einfache Möglichkeit, die SID für das aktuelle Windows-Benutzerkonto zu erhalten. Ich weiß, dass ich es durch WMI tun kann, aber ich will nicht, diesen Weg zu gehen.

Apologies an alle, die für die nicht spezifiziert ist es C in C # beantwortet ++. : -)

War es hilfreich?

Lösung

In Win32, rufen Sie GetTokenInformation , vorbei an einem Token Griff und die TokenUser konstant. Es füllt in einer TOKEN_USER Struktur für Sie. Eines der Elemente, da drin ist der SID des Benutzers. Es ist ein BLOB (binary), aber man kann es in einen String verwandeln, indem Sie ConvertSidToStringSid .

Um halten den aktuellen Token Griff zu bekommen, verwenden Sie Open oder Open .

Wenn Sie ATL bevorzugen, hat es die CAccessToken Klasse, die alle möglichen interessanten Dinge in sich hat.

.NET hat die Thread.CurrentPrinciple Eigenschaft, die ein IPrincipal Referenz zurückgibt. Sie können den SID erhalten:

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

Auch in .NET können Sie verwenden WindowsIdentity.GetCurrent (), die den aktuellen Benutzer-ID zurückgibt:

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

Andere Tipps

Das sollten Sie geben, was Sie brauchen:

mit System.Security.Principal;

...

var sid = WindowsIdentity.GetCurrent () Benutzer;.

Die User-Eigenschaft von Windows gibt den SID, pro MSDN Docs

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

Codeproject ein paar verschiedene Methoden hat, können Sie versuchen Sie ... nicht erwähnt, welche Sprachen Sie eine Lösung in.

gesucht

Wenn Sie es über eine Batch-Datei oder etwas zugreifen möchten, können Sie als PsGetSid aussehen von Sysinternals . Er übersetzt SIDs Namen und umgekehrt.

In C # können Sie verwenden entweder

using Microsoft.Win32.Security;

...

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

Sid sidUser = new Sid (username);

oder ...

using System.Security.AccessControl;

using System.Security.Principal;

...

WindowsIdentity m_Self = WindowsIdentity.GetCurrent();

SecurityIdentifier m_SID = m_Self.Owner;");

fand ich eine andere Art und Weise SID zu erhalten:

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

Und in nativen Code:

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

Sie hat nicht angegeben, welche Sprache Sie wollen. Aber wenn Sie für C # vorhast dieser Artikel bietet sowohl die WMI-Methode sowie eine schnellere (während ausführlicher) Methode, um die Win32-API verwendet wird.

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

Ich glaube nicht, dass es noch eine andere Möglichkeit, dies zu tun, ohne WMI oder die Win32-API.

Dies ist die kürzeste von allen, glaube ich.

UserPrincipal.Current.Sid;

Erhältlich mit .net> = 3.5

Diese Frage als c++ markiert Und ich antworte in c++ Sprache, also ich empfehlen die Verwendung von WMI Werkzeug:

So, wie WMI Befehle in powershell, brüllen Befehl erhalten SID von system-pc1 Benutzer:

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

Zuerst müssen Sie aktuelle username mit Balg code bekommen:

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

Jetzt können Sie mit WQL Sprache versuchen und diese Abfrage in c++ als Gebrüll auszuführen (in diesem Beispiel habe ich von system-pc1 Benutzername in WQL_WIN32_USERACCOUNT_QUERY Abfrage:

#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();

Dieses Beispiel funktioniert ordnungsgemäß funktioniert!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top