Взять на себя ответственность за файл C#
Я пытаюсь стать владельцем файла и удалить его через C#. Файл iexplorer.exe, текущий владелец по умолчанию - TrustedInstaller. Метод FileSecurity.SetOwner, кажется, устанавливает указанное владение, но на самом деле не меняет первоначального владельца и не выдает никаких исключений. Очевидно, что следующая попытка удаления файла вызывает исключение. Что нужно изменить в коде, чтобы стать владельцем файла и удалить его?
var fileS = File.GetAccessControl(@"C:\Program Files (x86)\Internet Explorer\iexplore.exe");
fileS.SetOwner(new System.Security.Principal.NTAccount(Environment.UserDomainName, Environment.UserName));
File.Delete(@"C:\Program Files (x86)\Internet Explorer\iexplore.exe");
3 ответа
Вы должны явно включить SeTakeOwnershipPrivilege
:
Требуется вступить во владение объектом без предоставления дискреционного доступа. Эта привилегия позволяет устанавливать значение владельца только для тех значений, которые держатель может на законных основаниях назначить владельцем объекта. Право пользователя: взять на себя ответственность за файлы или другие объекты.
Я предлагаю вам прочитать замечательную статью, написанную Марком Новаком: Управляйте привилегиями в управляемом коде надежно, надежно и эффективно.
И / или взглянуть на его образец.
Обновить
Пример использования:
var fileS = File.GetAccessControl(@"C:\Program Files (x86)\Internet Explorer\iexplore.exe");
Privilege p;
bool ownerChanged = false;
try
{
p = new Privilege(Privilege.TakeOwnership);
p.Enable();
fileS.SetOwner(new System.Security.Principal.NTAccount(
Environment.UserDomainName, Environment.UserName));
ownerChanged = true;
}
catch(PrivilegeNotHeldException e)
{
// privilege not held
// TODO: show an error message, write logs, etc.
}
finally
{
p.Revert();
}
if (ownerChanged)
File.Delete(@"C:\Program Files (x86)\Internet Explorer\iexplore.exe");
string filepath = @"C:\Program Files (x86)\Internet Explorer\iexplore.exe";
//Get Currently Applied Access Control
FileSecurity fileS = File.GetAccessControl(filepath);
//Update it, Grant Current User Full Control
SecurityIdentifier cu = WindowsIdentity.GetCurrent().User;
fileS.SetOwner(cu);
fileS.SetAccessRule(new FileSystemAccessRule(cu, FileSystemRights.FullControl, AccessControlType.Allow));
//Update the Access Control on the File
File.SetAccessControl(filepath, fileS);
//Delete the file
File.Delete(filepath);
Добавьте следующий импорт
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
Запустите код в повышенном режиме.
Работает в Windows 8.1 с использованием класса Privilege из примера: управляйте привилегиями в управляемом коде надежно, безопасно и эффективно
private bool TryDeleteFile(string fileName)
{
string filePath = Path.GetFullPath(fileName);
var fi = new FileInfo(filePath);
bool ownerChanged = false;
bool accessChanged = false;
bool isDelete = false;
FileSecurity fs = fi.GetAccessControl();
Privilege p = new Privilege(Privilege.TakeOwnership);
try
{
p.Enable();
fs.SetOwner(WindowsIdentity.GetCurrent().User);
File.SetAccessControl(filePath, fs); //Update the Access Control on the File
ownerChanged = true;
}
catch (PrivilegeNotHeldException ex) { }
finally { p.Revert(); }
try
{
fs.SetAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, AccessControlType.Allow));
File.SetAccessControl(filePath, fs);
accessChanged = true;
}
catch (UnauthorizedAccessException ex) { }
if (ownerChanged && accessChanged)
{
try
{
fi.Delete();
isDelete = true;
}
catch (Exception ex) { }
}
return isDelete;
}
См. Эти записи реестра для добавления контекстного меню. Мне удалось переименовать папку, а также iexplorer_OFF.exe в Windows 7. Вы, вероятно, можете выполнить оболочку / выполнить то же самое из своего кода.