2016-10-14 11 views
1

У меня возникла проблема с запущенным процессом, в котором еще не создан каталог профиля пользователя процесса.Как заставить Windows создать каталог профиля текущего пользователя

Объяснить, вот детали того, как это происходит:

Мы проводим большую сетку распределенного сервера, и используя (части) DataSynapse для выполнения процессов на этой сетке. Для тех, кто знаком с DataSynapse, Engine сконфигурирован для запуска конкретной службы с помощью «RunAs», где мы используем определенную учетную запись службы домена AD для процессов обслуживания. Я считаю, что проблема заключается в том, что DataSynapse при запуске процесса под «runas» не устанавливает флаг LoadUserProfile (и не должен). Какова бы ни была точная причина, если учетная запись службы «runas» (и учетная запись домена AD) никогда не входила в систему на некоторых сетчатых машинах, тогда у этих машин не будет каталога профиля пользователя для учетной записи.

Для тех, кто не знаком с DataSynapse, приведено более общее объяснение. На каждой машине в сетке выполняется процесс, я назову его dsService, и он запускается под учетными данными системной учетной записи локального компьютера (или другой подобной учетной записи с повышенными учетными данными). Процесс dsService породит дочерний процесс, скажем childProcess, но он запускает childProcess под учетными данными нашей учетной записи домена AD, которую я назову serviceUser. В сетке тысячи компьютеров, и, как правило, они никогда не регистрируются вручную. В частности, каталог профилей C:\users\serviceUser может не существовать первоначально. Как только он создается один раз, проблем больше нет. Но если новые узлы будут добавлены в сетку, то обычно они не будут иметь C:\users\serviceUser изначально. Проблема в том, что когда dsService порождает childProcess, C:\users\serviceUser не создается, и нам это нужно.

Я считаю, , что это происходит потому, что dsService не устанавливает флаг LoadUserProfile к истинным, когда нерест childProcess, хотя я не уверен.

В любом случае, childProcess является (.net) процесс (работает как serviceUser) под нашим контролем, и я хотел бы знать, если есть способ (в C#), что childProcess может заставить операционную систему, чтобы создать запустить каталог профиля пользователяC:\users\serviceUser, когда он определит, что он еще не существует?

Edit: Экспериментирования подтвердило, что если кто-то начинает процесс под другим идентификатором пользователя и каталог профиля пользователя не существует (точнее, если локального профиль пользователя не был создан еще - просто удаление предварительно существующий каталог профиля создает другую ситуацию, в любом случае мы не заинтересованы), тогда (1) создается каталог профиля (и один предполагает локальный профиль), если процесс начинается с LoadUserProfile, установленного в true; и (2) каталог профиля (и, предположительно, локальный профиль) НЕ создается, если процесс начинается с LoadUserProfile, установленным в false. Это имеет смысл и, как и следовало ожидать.

Похожие темы: stackoverflow.com/q/9008742/1082063

+0

Вам нужно использовать «User Directory?». Это похоже на тип приложения, которое должно сохранять свои данные в своем собственном каталоге программ или просто в каталоге, который он создает в другом месте на жестком диске ... –

+0

Нет, вы не можете сделать это из контекста пользователя. Если DataSynapse не предоставляет возможность создать профиль пользователя, и вы не можете обойти требование о том, чтобы профиль пользователя присутствовал, вам необходимо организовать запуск какого-либо кода в качестве локальной системы или другой учетной записи с привилегированной привилегией. –

+0

Во-первых, вы должны проверить, действительно ли достаточно создать профиль. Если ваш код требует, чтобы профиль был * инициализирован *, а не просто * загружен *, у вас возникла более сложная проблема. Единственный способ инициализировать профиль - это интерактивный вход в систему. –

ответ

0

Если текущий счет имеет права администратора, следующий код приведет к созданию профиля текущего счета, в том числе его каталог UserProfile.Без администратора, я не знаю, если это возможно:

using System.Runtime.InteropServices; 
... 
[DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern int CreateProfile(
    [In] string pszUserSid, 
    [In] string pszUserName, 
    System.Text.StringBuilder pszProfilePath, 
    int cchProfilePath); 

.... 
public static string getUserProfilePath() 
{ 
    string userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); 
    if(string.IsNullOrWhiteSpace(userProfilePath) || !Directory.Exists(userProfilePath)) 
    { //This will only work if we have admin... 
     var pathBuf = new System.Text.StringBuilder(240); 
     var Up = System.DirectoryServices.AccountManagement.UserPrincipal.Current; 
     if(0 == CreateProfile(Up.Sid.ToString(), Up.SamAccountName, pathBuf, pathBuf.Capacity) } 
     { 
      userProfilePath = pathBuf.ToString(); 
     } 
    } 
    return userProfilePath; 
} 

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