سؤال

وهناك سؤال حول <لأ href = "https://stackoverflow.com/questions/499053/how-can-i-convert-from-a-sid-to-an-account-name-in-c" > التحويل من SID إلى اسم حساب . لم يكن هناك احد للالعكس.

وكيف قمت بتحويل اسم المستخدم إلى سلسلة SID، على سبيل المثال، لمعرفة أي HKEY_USERS الفرعي يتصل مستخدم من اسم معين؟

هل كانت مفيدة؟

المحلول

ووبودكاست يقول لي أنني يجب أن نسأل، والإجابة، أسئلة انهم عندما لم تجب على SO بالفعل. هنا يذهب.

وطريقة سهلة، مع الصافي 2.0 وما فوق، هو هذا:

NTAccount f = new NTAccount("username");
SecurityIdentifier s = (SecurityIdentifier) f.Translate(typeof(SecurityIdentifier));
String sidString = s.ToString();

وهذا الطريق الصعب، والذي يعمل عندما لا ان صح التعبير، ويعمل على .NET Framework 1.1 أيضا:

[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool LookupAccountName([In,MarshalAs(UnmanagedType.LPTStr)] string systemName, [In,MarshalAs(UnmanagedType.LPTStr)] string accountName, IntPtr sid, ref int cbSid, StringBuilder referencedDomainName, ref int cbReferencedDomainName, out int use);

[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern bool ConvertSidToStringSid(IntPtr sid, [In,Out,MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid);


/// <summary>The method converts object name (user, group) into SID string.</summary>
/// <param name="name">Object name in form domain\object_name.</param>
/// <returns>SID string.</returns>
public static string GetSid(string name) {
    IntPtr _sid = IntPtr.Zero; //pointer to binary form of SID string.
    int _sidLength = 0;   //size of SID buffer.
    int _domainLength = 0;  //size of domain name buffer.
    int _use;     //type of object.
    StringBuilder _domain = new StringBuilder(); //stringBuilder for domain name.
    int _error = 0;
    string _sidString = "";

    //first call of the function only returns the sizes of buffers (SDI, domain name)
    LookupAccountName(null, name, _sid, ref _sidLength, _domain, ref _domainLength, out _use);
    _error = Marshal.GetLastWin32Error();

    if (_error != 122) //error 122 (The data area passed to a system call is too small) - normal behaviour.
    {
        throw (new Exception(new Win32Exception(_error).Message));
    } else {
        _domain = new StringBuilder(_domainLength); //allocates memory for domain name
        _sid = Marshal.AllocHGlobal(_sidLength); //allocates memory for SID
        bool _rc = LookupAccountName(null, name, _sid, ref _sidLength, _domain, ref _domainLength, out _use);

        if (_rc == false) {
            _error = Marshal.GetLastWin32Error();
            Marshal.FreeHGlobal(_sid);
            throw (new Exception(new Win32Exception(_error).Message));
        } else {
            // converts binary SID into string
            _rc = ConvertSidToStringSid(_sid, ref _sidString);

            if (_rc == false) {
                _error = Marshal.GetLastWin32Error();
                Marshal.FreeHGlobal(_sid);
                throw (new Exception(new Win32Exception(_error).Message));
            } else {
                Marshal.FreeHGlobal(_sid);
                return _sidString;
            }
        }
    }
}

نصائح أخرى

وأسلوب الأصلي LookupAccountName() لديه ميزة كونها قادرة ليتم تنفيذها على جهاز بعيد في حين أن الطرق. NET لا يمكن تنفيذها عن بعد.

وعلى الرغم من أن المثال لا تظهر عليه LookupAccountName(null) <-. هذا هو النظام البعيد لتنفيذ على

using System;
using System.Management;
using System.Windows.Forms;

namespace WMISample
{
public class MyWMIQuery
{
    public static void Main()
    {
        try
        {
            ManagementObjectSearcher searcher = 
                new ManagementObjectSearcher("root\\CIMV2", 
                "SELECT * FROM Win32_UserAccount where name='Galia'"); 

            foreach (ManagementObject queryObj in searcher.Get())
            {
                Console.WriteLine("-----------------------------------");
                Console.WriteLine("Win32_UserAccount instance");
                Console.WriteLine("-----------------------------------");
                Console.WriteLine("Name: {0}", queryObj["Name"]);
                Console.WriteLine("SID: {0}", queryObj["SID"]);
            }
        }
        catch (ManagementException e)
        {
            MessageBox.Show("An error occurred while querying for WMI 
            data: " + e.Message);
        }
      }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top