Проблема с разрешениями при запуске приложения .NET из службы .NET от имени другого пользователя? - PullRequest
24 голосов
/ 18 января 2010

Я пытаюсь запустить приложение .NET под другим пользователем из службы .NET. Идея состоит в том, чтобы создать изолированное хостинговое приложение в Windows. В службе я программно создал пользователя в Windows, создал папку для этого пользователя и загрузил в эту папку файл .exe с сервера. Затем я запускаю хост .exe, используя System.Diagnostics.Process. Вот StartInfo для процесса:

_process = new Process
{
    StartInfo =
    {
        Arguments = " -debug",
        FileName = instanceDirectory + "host.exe",
        WorkingDirectory = instanceDirectory,
        UseShellExecute = false,
        RedirectStandardError = true,
        RedirectStandardOutput = true,
        RedirectStandardInput = true,
        UserName = Helpers.GetUserNameForInstance(_hostid),
        Password = _hostpass,
        Domain = ""
    },
    EnableRaisingEvents = true
};

Когда я запускаю службу как СЕРВИС, процесс мгновенно завершает работу с кодом ошибки -1073741502. но когда я запускаю службу от имени того же пользователя, который указан в службе Windows, но в интерактивном режиме в консоли, все работает нормально. Это происходит только тогда, когда служба запускается как СЕРВИС, а не непосредственно в консоли.

Любая помощь будет очень признательна. Это было головной болью в течение долгого времени, и это последнее средство: (

Ответы [ 4 ]

14 голосов
/ 19 января 2010

Похоже на использование new Process() с именем пользователя и паролем, а сервисный режим "не вычисляется":)

Цитата из MSDN:

Вы можете изменить параметры указывается в свойстве StartInfo к тому времени, когда вы называете старт метод на процессе. После начала процесс, меняющий StartInfo значения не влияют или перезапускают связанный процесс. Если вы позвоните Метод Start (ProcessStartInfo) с ProcessStartInfo .. ::. UserName и ProcessStartInfo .. ::. Пароль свойства установлены, неуправляемые Функция CreateProcessWithLogonW называется, который запускает процесс в новое окно, даже если CreateNoWindow Значение свойства true или Значение свойства WindowStyle скрыто.

Кроме того, посмотрите документацию CreateProcessWithLogonW:

lpStartupInfo [in]

Указатель на структуру STARTUPINFO. Приложение должно добавить разрешение для указанного пользователя аккаунт в указанное окно станция и рабочий стол, даже для Winsta0 \ Default.

Если элемент lpDesktop имеет значение NULL или пустую строку, новый процесс наследует рабочий стол и окно станция его родительского процесса. Приложение должно добавить разрешение для указанная учетная запись пользователя в Унаследованная оконная станция и рабочий стол.

В .NET StartupInfo нет lpDesktop, с другой стороны, у пользователя SERVICE нет рабочего стола, что может привести к вашей проблеме.

Короче говоря, попробуйте установить LoadUserProfile в true, чтобы загрузить информацию о пользователе из реестра, или, возможно, вам нужно установить рабочий каталог и т. Д.

Для дальнейшего изучения вам следует проверить свою среду и, возможно, записать, какие файлы доступны с помощью FileMon.

5 голосов
/ 20 декабря 2012

Я бы попытался создать процесс в олицетворенном контексте вновь созданного пользователя, как показано ниже.

[DllImport("advapi32.DLL", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);

static void Main()
{             
    IntPtr admin_token = new IntPtr();
    WindowsIdentity wid_admin = null;
    WindowsImpersonationContext wic = null;

    LogonUser("username", "domain", "password", 9, 3, out admin_token);
    wid_admin = new WindowsIdentity(admin_token);
    wic = wid_admin.Impersonate();

    _process = new Process
    {
        StartInfo =
        {
            Arguments = " -debug",
            FileName = instanceDirectory + "host.exe",
            WorkingDirectory = instanceDirectory,
            UseShellExecute = false,
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            RedirectStandardInput = true,
            UserName = Helpers.GetUserNameForInstance(_hostid),
            Password = _hostpass,
            Domain = ""
        },
        EnableRaisingEvents = true
    };

    if (wic != null) wic.Undo();
    CloseHandle(admin_token);
}
3 голосов
/ 18 января 2010

Двойной переход между серверами может привести к потере учетных данных службы, возможно, настройка Kerberos решит эту проблему.

http://neverknewthat.wordpress.com/2009/05/14/kerberos/

1 голос
/ 18 января 2010

0xc0000142 (-1073741502) равно STATUS_DLL_INIT_FAILED:

Ошибка инициализации библиотеки динамических ссылок [имя]. Процесс ненормально завершается.

Как указал веб-сайт TenaciousImpy, вам необходимо предоставить разрешения учетной записи для оконной станции и рабочего стола. Но если программа является интерактивной, вам также необходимо установить идентификатор сеанса токена процесса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...