jetzt genau mein Code ImpersonationService
Code: Select all
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace PharmaServiceManager.Service;
public class ImpersonationService : IDisposable
{
private readonly CredentialManager _credentialManager;
private IntPtr _userToken = IntPtr.Zero;
private WindowsIdentity? _windowsIdentity;
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
public ImpersonationService(CredentialManager credentialManager)
{
_credentialManager = credentialManager;
}
public void Impersonate()
{
if (!_credentialManager.AreCredentialsSet)
{
throw new InvalidOperationException("Облікові дані не встановлені. Переконайтеся, що всі дані введені.");
}
if (!LogonUser(
_credentialManager.Username,
_credentialManager.Domain,
_credentialManager.Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
out _userToken))
{
int errorCode = Marshal.GetLastWin32Error();
throw new UnauthorizedAccessException($"Помилка входу: {errorCode}");
}
_windowsIdentity = new WindowsIdentity(_userToken);
}
public async Task RunImpersonatedAsync(Func action)
{
if (_windowsIdentity == null)
{
throw new InvalidOperationException("Імпонізація була виконана. Спочатку викличте метод Impersonate.");
}
await Task.Run(() => WindowsIdentity.RunImpersonated(_windowsIdentity.AccessToken, () => action().Wait()));
}
public void Dispose()
{
if (_userToken != IntPtr.Zero)
{
CloseHandle(_userToken);
_userToken = IntPtr.Zero;
}
_windowsIdentity?.Dispose();
_windowsIdentity = null;
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool LogonUser(
string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
out IntPtr phToken);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
}
Code: Select all
using PharmaServiceManager.ConstanceValues;
using PharmaServiceManager.ConstanceValues.Enums;
using PharmaServiceManager.Model.FormModels;
using System.Diagnostics;
using System.ServiceProcess;
using Telerik.WinControls.VirtualKeyboard;
namespace PharmaServiceManager.Service
{
public class ServiceControllerService
{
private readonly ImpersonationService _impersonationService;
public ServiceControllerService(ImpersonationService impersonationService)
{
_impersonationService = impersonationService;
}
public async Task ManageAction(Func action)
{
var operationResult = new OperationResult();
try
{
await _impersonationService.RunImpersonatedAsync(async () =>
{
operationResult = await action();
});
}
catch (Exception ex)
{
operationResult.Status = ServiceStatus.Error;
operationResult.MessageErrors.Add($"Ошибка выполнения действия: {ex.Message}");
}
return operationResult;
}
public async Task ManageService(string serviceName, string computerName, Func action)
{
var operationResult = new OperationResult { ComputerName = computerName };
try
{
await _impersonationService.RunImpersonatedAsync(async () =>
{
using (var service = new ServiceController(serviceName, computerName))
{
operationResult = await action(service);
}
});
}
catch (Exception ex)
{
operationResult.Status = ServiceStatus.Error;
operationResult.MessageErrors.Add($"Ошибка управления службой: {ex.Message}");
}
return operationResult;
}
public Task StatusService(string serviceName, string computerName)
{
return ManageService(serviceName, computerName, async service =>
{
var result = new OperationResult { ComputerName = computerName };
result.Status = (ServiceStatus)service.Status;
return result;
});
}
public Task FarService(string computerName)
{
return ManageAction(async () =>
{
var result = new OperationResult { ComputerName = computerName, Status = ServiceStatus.Error };
try
{
if (!string.IsNullOrEmpty(computerName))
{
var logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FarManagerLog.txt");
File.AppendAllText(logPath, $"Запуск Far Manager для {computerName}...\n");
var processInfo = new ProcessStartInfo
{
FileName = @"D:\Git\InternetSalesApteka\PharmaServiceManager\Far Manager\far.exe",
Arguments = @$"\\{computerName}\c$\", // Доступ к корню диска C$
};
using (var process = Process.Start(processInfo))
{
await process?.WaitForExitAsync();
result.Status = process.ExitCode == 0 ? ServiceStatus.Running : ServiceStatus.Error;
}
}
}
catch (Exception ex)
{
result.Status = ServiceStatus.Error;
result.MessageErrors.Add($"Ошибка запуска Far Manager: {ex.Message}");
}
return await Task.FromResult(result);
});
}
}
}
für den Anfang i habe versucht, beim Starten von ProcessStartInfo mehr Berechtigungen zu erteilen, habe außerdem eine neue ManageAction-Methode getrennt von ManageService erstellt, aber nichts