Как изменить права доступа к текущему пользователю с помощью учетных данных администратора?

Хорошо, поэтому я искал какое-то время, и название объясняет в значительной степени то, что я хочу сделать. Кроме того, нет проблем с жестким кодированием учетных данных администратора в коде.

Сначала я написал код в c #, который ALMOST решил проблему:

private void button2_Click(object sender, EventArgs e) { DirectoryInfo myDirectoryInfo = new DirectoryInfo(textBox1.Text); DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl(); string User = System.Environment.UserDomainName + "\\" + comboBox1.SelectedItem.ToString(); myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(User, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow)); //myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(User, FileSystemRights.Write, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow)); myDirectoryInfo.SetAccessControl(myDirectorySecurity); MessageBox.Show("Permissions Altered Successfully" + User); } 

Это работает отлично, если я использую в папке, у которой у меня уже есть разрешение, но мне нужен метод, который использует учетные данные администратора, чтобы предоставить разрешение на папку, которую обычный пользователь не имеет.

Позже я попытался написать кое-что в vbscript:

  strHomeFolder = "C:\test" strUser = " DOMAIN\user" Set WshShell = CreateObject("WScript.Shell") WshShell.Run "%COMSPEC% /c Echo Y| cacls "& strHomeFolder & " /e /c /g "& strUser &":F", 2, True 

Но я не мог найти способ передать учетные данные администратора. Поэтому, наконец, я написал еще один код, чтобы попытаться сделать это:

 private void button1_Click(object sender, EventArgs e) { try { //string passwordPre = "PASSWORD"; //char[] passwordChars = passwordPre.ToCharArray(); //SecureString password = new SecureString(); //foreach (char c in passwordChars) //{ // password.AppendChar(c); //} ProcessStartInfo p = new ProcessStartInfo(@"D:\\test.vbs"); //p.UseShellExecute = false; //p.UserName = "username"; //p.Domain = "DOMAIN"; //p.Password = password; Process.Start(p); } catch (Exception ex) { MessageBox.Show(ex.Message); } } 

На этот раз я просто попытался передать учетные данные администратора с помощью процесса, но он сгенерировал сообщение: указанный исполняемый файл не является допустимым приложением для этой платной формы ОС.

Итак, есть ли какой-либо метод, который я могу использовать для передачи учетных данных? (Может быть в c # или vbscript).

Заранее спасибо.

Олицетворение решит вашу проблему. Когда вы выполняете код внутри олицетворенного контекста, логика, размещенная внутри этого контекста, будет выполняться с предикатом олицетворенного пользователя. Следуя указаниям classа, введите значения параметров олицетворения из файла web.config. Вы можете изменить его, прочитав из app.config или независимо от источника.

Требуемые конфигурации

  1. Имя пользователя
  2. пароль
  3. Доменное имя

Класс олицетворения

  public class Impersonator : IDisposable { #region Win32 Advanced API calls ///  /// Logons the user. ///  /// Name of the LPSZ user. /// The LPSZ domain. /// The LPSZ password. /// Type of the dw log on. /// The dw log on provider. /// The ph token. ///  [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] private static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogOnType, int dwLogOnProvider, ref IntPtr phToken); ///  /// Duplicates the token. ///  /// The h token. /// The impersonation level. /// The h new token. ///  [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); ///  /// Reverts to self. ///  ///  [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] private static extern bool RevertToSelf(); ///  /// Closes the handle. ///  /// The handle. ///  [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] private static extern bool CloseHandle(IntPtr handle); #endregion #region Fields ///  /// Field to hold the impersonation Context ///  WindowsImpersonationContext impersonationContext; ///  /// Track whether Dispose has been called. ///  private bool disposed; #region Constants ///  /// Logon32 Logon Interactive ///  public const int INTERACTIVE_NUMBER = 2; ///  /// Logon32 Provider Default ///  public const int DEFAULT_NUMBER = 0; ///  /// Impersonating user name key ///  public const string ImpersonatingUserNameKey = "ImpersonatingUserName"; ///  /// Impersonating user password key ///  public const string ImpersonatingPasswordKey = "ImpersonatingUserPassword"; ///  /// Impersonating user domain key ///  public const string ImpersonatingDomainNameKey = "ImpersonatingDomain"; #endregion #endregion #region Construction/Destruction/Initialization ///  /// Constructor of the impersonator ///  public Impersonator() { if (!ImpersonateUser(ConfigurationManager.AppSettings[ImpersonatingUserNameKey], ConfigurationManager.AppSettings[ImpersonatingDomainNameKey], ConfigurationManager.AppSettings[ImpersonatingPasswordKey])) { //TODO: Log Exception } } #endregion #region Public Methods // Implement IDisposable. // Do not make this method virtual. // A derived class should not be able to override this method. public void Dispose() { Dispose(true); // This object will be cleaned up by the Dispose method. // Therefore, you should call GC.SupressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); } ///  /// Impersonate User with the given user credentials ///  /// User Name /// Domain /// Password /// True if success, false otherwise private bool ImpersonateUser(String userName, String domain, String password) { WindowsIdentity tempWindowsIdentity; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; if (RevertToSelf()) { if (LogonUser(userName, domain, password, INTERACTIVE_NUMBER, DEFAULT_NUMBER, ref token) != 0) { if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) { tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); impersonationContext = tempWindowsIdentity.Impersonate(); if (impersonationContext != null) { CloseHandle(token); CloseHandle(tokenDuplicate); return true; } } } } if (token != IntPtr.Zero) CloseHandle(token); if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate); return false; } ///  /// Undo impersonation ///  private void StopImpersonation() { impersonationContext.Undo(); } #endregion #region Protected Methods // Dispose(bool disposing) executes in two distinct scenarios. // If disposing equals true, the method has been called directly // or indirectly by a user's code. Managed and unmanaged resources // can be disposed. // If disposing equals false, the method has been called by the // runtime from inside the finalizer and you should not reference // other objects. Only unmanaged resources can be disposed. protected virtual void Dispose(bool disposing) { // Check to see if Dispose has already been called. if (!this.disposed) { // If disposing equals true, dispose all managed // and unmanaged resources. if (disposing) { StopImpersonation(); } // Note disposing has been done. disposed = true; } } #endregion } 

Как вызвать метод

 Using(Impersonator impersonator = new Impersonator()) { //Write the folder accessing logic here }