Работа с системными каталогами Windows, такими как System32
, требует особых привилегий. В этой статье мы рассмотрим, как на языке C# копировать, удалять и модифицировать файлы в защищённых директориях даже при включённой системе контроля учётных записей (UAC). Чтобы ваш код работал корректно, потребуется запуск от имени администратора, а проект рекомендуется собирать с конфигурацией Any CPU
для совместимости с 32- и 64-битными системами.
Теперь добавим класс DisableFsRedirection в свой проект.
sealed class DisableFsRedirection : IDisposable
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);
[ThreadStatic] IntPtr _oldValue;
[ThreadStatic] bool _revert;
public DisableFsRedirection()
{
_oldValue = IntPtr.Zero;
try
{
_revert = Wow64DisableWow64FsRedirection(ref _oldValue);
}
catch (EntryPointNotFoundException)
{
GC.SuppressFinalize(this);
}
}
~DisableFsRedirection()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
void Dispose(bool disposing)
{
if (disposing)
{
GC.SuppressFinalize(this);
}
if (_revert)
{
Wow64RevertWow64FsRedirection(_oldValue);
_oldValue = IntPtr.Zero;
_revert = false;
}
}
}
И теперь мы можем с помощью этого класса, использовать обычные методы копирования, удаления файла.
using (new DisableFsRedirection())
{
File.Copy(@"C:\Windows\System32\сmd.exe", @"C:\Windows\System32\cmd.exe");
}
А с помощью следующего метода мы можем изменить разрешения на доступ к файлу. Его вы можете посмотреть в свойствах файла в разделе безопасность. В приведённом ниже листинге полный доступ к файлу будет получен текущим пользователем, так же в нем можно изменить на любую группу пользователя.
String filename = @"C:\Windows\System32\cmd.exe";
WindowsIdentity identity = WindowsIdentity.GetCurrent();
var account = new NTAccount(identity.Name);
FileSecurity fSecurity = File.GetAccessControl(filename);
fSecurity.RemoveAccessRule(new FileSystemAccessRule(account, FileSystemRights.FullControl, AccessControlType.Deny));
fSecurity.AddAccessRule(new FileSystemAccessRule(account, FileSystemRights.FullControl, AccessControlType.Allow));
File.SetAccessControl(filename, fSecurity);
Второй вариант кода:
using System;
using System.IO;
using System.Security.Principal;
class Program
{
static void Main()
{
// Проверяем, запущено ли приложение с правами администратора
if (!IsRunningAsAdmin())
{
Console.WriteLine("Приложение должно быть запущено с правами администратора.");
return;
}
string sourceFile = @"C:\Test\example.txt";
string destPath = @"C:\Windows\System32\example.txt";
try
{
// Копирование файла
File.Copy(sourceFile, destPath, true);
Console.WriteLine("Файл успешно скопирован.");
// Удаление файла
File.Delete(destPath);
Console.WriteLine("Файл успешно удалён.");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Недостаточно прав. Запустите приложение как администратор.");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка: {ex.Message}");
}
}
// Проверка прав администратора
static bool IsRunningAsAdmin()
{
var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
Дополнительные рекомендации:
- При запуске приложения убедитесь, что манифест включает
"requireAdministrator"
в секцииrequestedExecutionLevel
. - Для корректной работы с UAC в Visual Studio установите флаг «Run this program as administrator» в свойствах .exe-файла.
- Используйте конфигурацию Any CPU для универсальности проекта.