如何强制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

如何强制Windows创建正在运行的用户'

如果运行帐户具有管理员权限,则下面的代码将创建运行帐户的配置文件,包括其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;
}

如果有人能告诉我如何做到这一点,当帐户不是管理员,他们会得到他们的答案被接受为正确的答案。在此之前,这至少给了其他人一些想法。