我有一个 .NET 可执行文件(我创建的),它使用 Microsoft 的Active Directory 服务接口(通过 System.DirectoryServices.AccountManagement)执行 LDAP 查询。在 ADSI 内部,下载 Active Directory 架构并将其存储在本地。它应该将此模式存储在文件夹中%LOCALAPPDATA%\Microsoft\Windows\SchCache\
。
当我安排这个可执行文件任务计划程序在 Windows Server 2012 R2 上并将其设置为以“UserA”身份运行即使该用户尚未登录,程序运行,但它试图将上述缓存文件写入文件夹字面意思为%LOCALAPPDATA%\Microsoft\Windows\SchCache\
在开始计划任务的文件夹(故意将其设置为我的可执行文件的文件夹)。换句话说,它正在写入类似的东西C:\MyApp\%LOCALAPPDATA%\Microsoft\Windows\SchCache\
。我必须授予 UserA 对此文件夹的明确写入权限,以允许程序正常运行。
我用进程监视器观察了任务的进程,它立即进入该文件夹。这并不是说它先尝试了某项操作C:\Users\
但失败了。
当我以自己的用户身份登录服务器并通过使用以其他用户身份运行,可执行文件运行并成功将缓存文件写入C:\Users\UserA\AppData\Local\Microsoft\Windows\SchCache\
。
为什么任务计划程序会发生这种情况?我该怎么做才能修复它?我想这可能与任务计划程序在用户 A 的上下文中执行程序但没有初始化%LOCALAPPDATA%
为环境变量有关。一时兴起,我尝试设置以最高权限运行完成任务,但结果并没有改变。
答案1
这是 Windows Server 2012 R2 和 8.1 中的一个错误;Microsoft 已将其记录在知识库 2968540。
问题已修复并已修复知识库 3133689可用。此修补程序确实解决了该问题。
使用 UBPM 运行的计划任务在启动相应进程时没有足够的环境变量,例如 APPDATA、USERPROFILE 或 TEMP。
答案2
我认为 Windows 7 / 2012 计划任务中存在一个错误,因此它们无法看到以下列用户身份运行的正确环境变量:
https://stackoverflow.com/questions/32589381/
为了确认这种情况确实发生了,您可以SET>test.txt
在同一个用户上下文中,在计划任务中运行批处理文件。当我尝试这样做时,它确实不是显示指定用户的正确、完整的环境变量集;即,与实际以该用户身份登录时运行相同命令(或批处理文件)时看到的环境变量集不同。(更令人困惑的是,这取决于计划任务运行时用户当前是否登录;如果用户已登录,则任务做查看正确的变量。
我认为这种行为没有记录或预期,并且是 Windows Server 2012(可能只是 R2?)处理计划任务方式的一个错误。
注意:这PATH
也适用于变量,因此计划任务只能看到位于默认路径、当前目录或完整指定的路径。调用指定用户路径上但不在默认路径上的任何内容,将产生难以调试的错误(因为它在测试中有效!)。
答案3
这是 Windows 处理用户帐户的方式所导致的结果。当用户帐户未登录时,其用户注册表配置单元(HKEY_USERS
通常映射为的注册表项HKEY_CURRENT_USER
)未安装。该配置单元(存储在每个用户配置文件中的名为的文件中NTUSER.DAT
)存储几乎所有每个用户的数据,包括每个用户的环境变量。Windows 还有系统环境变量 - 某些变量(例如 PATH)存在于两个位置并合并 - 因此即使未安装用户的注册表配置单元,这些变量也会显示出来。但是,用户特定的配置单元均不会显示出来。
我不知道任务计划程序在其他 Windows 版本中是否以不同的方式处理这种情况。它可以在以该用户身份运行任务之前,能够足够智能地挂载用户的配置单元。在 Win7 / 2012R2 中,显然不是这样。
要解决此问题,您需要确保用户的注册表配置单元已安装。最简单的方法是确保用户已登录,因为登录用户的配置单元始终已安装。如果没有,您可以尝试自己安装配置单元(API 是RegLoadKey
但我从未尝试过调用它来实现这一点)