如何强制Windows创建正在运行的用户'
本文关键字:用户 运行 何强制 Windows 创建 | 更新日期: 2023-09-27 18:13:18
我遇到一个正在运行的进程的问题,其中进程用户的配置文件目录尚未创建。
为了解释这一点,下面是如何发生的细节:
我们运行一个大型的分布式服务器网格,并且使用(部分)DataSynapse在这个网格上执行进程。对于那些熟悉DataSynapse的人来说,引擎被配置为使用"RunAs"运行特定的服务,其中我们为服务进程使用特定的AD域服务帐户。我认为问题是,DataSynapse,当运行"runas"下的进程,不设置LoadUserProfile
标志(也不应该)。无论确切的原因是什么,如果"runas"服务帐户(和AD域帐户)从未登录到某些网格机器,那么这些机器将没有该帐户的用户配置文件目录。
对于那些不熟悉DataSynapse的人,这里有一个更通用的解释。在网格中的每台机器上,都有一个进程在运行,我将其称为dsService
,它在本地机器的系统帐户(或具有提升凭据的类似帐户)的凭据下运行。进程dsService
将产生一个子进程,例如childProcess
,但是它在AD域帐户的凭据下运行childProcess
,我将其称为serviceUser
。网格上有成千上万台机器,通常它们都不需要手动登录。特别是,配置文件目录C:'users'serviceUser
最初可能不存在。一旦创建了一次,就不会再有问题了。但是如果新节点被添加到网格中,通常它们最初不会有C:'users'serviceUser
。问题是,当dsService
生成childProcess
时,C:'users'serviceUser
没有被创建,而我们需要它。
我相信这是因为dsService
在生成childProcess
时不将LoadUserProfile
标志设置为true,尽管我不确定。
在任何情况下,childProcess
是一个(.net)进程(作为serviceUser
运行)在我们的控制下,和我想知道是否有一种方法(在c#中),childProcess
可以强制操作系统创建运行用户的配置文件目录 C:'users'serviceUser
,当它确定它还不存在?
编辑:实验已经证实,如果一个人在另一个用户ID下启动一个进程,而用户的配置文件目录不在那里(更具体地说,如果用户的本地配置文件还没有创建——仅仅删除一个预先存在的配置文件目录就会创建一个不同的情况,一个我们无论如何都不感兴趣的情况),那么(1)如果进程在LoadUserProfile
设置为true时启动,则创建配置文件目录(假设是本地配置文件);(2)如果进程启动时将LoadUserProfile
设置为false,则不会创建配置文件目录(假设是本地配置文件)。这是有道理的,正如人们所期望的那样。
相关帖子:stackoverflow.com/q/9008742/1082063
如果运行帐户具有管理员权限,则下面的代码将创建运行帐户的配置文件,包括其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;
}
如果有人能告诉我如何做到这一点,当帐户不是管理员,他们会得到他们的答案被接受为正确的答案。在此之前,这至少给了其他人一些想法。