我正在尝试编写一个执行两项操作的批处理文件:
除了安装程序需要管理员权限并且必须在用户上下文中运行之外,这将是相对简单的.即使有这些限制,这仍然是相对简单的,除了我在Azure Worker Role上运行它,这意味着两件事:
因此,解决方案似乎是在真实用户上下文中将安装程序作为任务计划程序任务运行.但是,这需要注意我需要在启动program.exe之前等待此任务完成.
因此,我的问题是:如何等待任务计划程序任务完成批处理文件?
或者,我可以在单个任务计划程序任务中以菊花链形式连接我的批处理文件中的两个调用(任务计划程序在单个任务中最多支持16个连续事件[需要引证]).
不过,如果我采取这种做法我的批处理文件将尽快任务终止计划,不只要它完成.不幸的是,我必须等到它才能完成我的工作者角色中的任何逻辑.但是,如果我可以检查任务计划程序任务是否已完成C#(没有管理员权限),那么我可以在那里等待它.
因此,第二个可行的答案是问题:如何检查任务计划程序任务是否已从C#完成?
编辑:我想我会通过MC ND澄清以下答案:
从高级别开始,此命令检查任务是否正在运行,然后它会休眠并循环(如果是).
:loop
for /f "tokens=2 delims=: " %%f in ('schtasks /query /tn yourTaskName /fo list ^| find "Status:"' ) do (
if "%%f"=="Running" (
ping -n 6 localhost >nul 2>nul
goto loop
)
)
Run Code Online (Sandbox Code Playgroud)
该调用schtasks /query /tn yourTaskName /fo list输出如下内容:
Folder: \
HostName: 1234567890
TaskName: \yourTaskName
Next Run Time: 11/27/2030 11:40:00 PM
Status: Ready
Logon Mode: Interactive/Background …Run Code Online (Sandbox Code Playgroud) 我正在使用CreateProcessAsUser在用户指定的凭据下创建进程.
我发布了希望代码的相关部分.如果您想再看到更多内容,请与我们联系.
第一个登录用户获取令牌:
result = LogonUser(
username,
wcschr(username, '@') ? NULL : (domain ? domain : L"."),
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hrunastoken);
Run Code Online (Sandbox Code Playgroud)
然后我加载配置文件,将STARTUPINFO结构的lpDesktop值设置为NULL(这使得它使用调用进程的桌面),并调用CreateProcessAsUser:
result = CreateProcessAsUser(
hrunastoken,
NULL,
apptorun,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
envblock ? envblock : NULL,
NULL,
&si,
&pi);
Run Code Online (Sandbox Code Playgroud)
这很好 - 它登录并成功创建过程,并且该过程"有效".问题是它创建的窗口是黑色的,就像在我的程序启动的记事本进程的屏幕截图中一样:

可能相关的背景:
我的帐户是具有完全管理员权限的Windows 7计算机上的本地帐户,我使用该帐户登录.我使用psexec(Sysinternals实用程序)打开在本地系统帐户下以交互方式运行的命令提示符.我从该命令提示符启动我的程序.我传递给它的凭据来自我的帐户.
我没有对windowstations/desktops的权限做过任何事情; 我假设我创建的进程应该拥有权限,因为正在我的会话中创建进程并使用我已经登录的相同帐户 - 尽管首先通过SYSTEM帐户.使用Process Explorer,我看不到通过我的程序正常打开的进程对windowstation/desktop的值和句柄的权限有任何差异.也许这完全无关紧要.
我也不能使用CreateProcessWithLogonW函数,因为它必须在从SYSTEM帐户运行时工作 - 该函数以及Windows附带的"runas"程序在SYSTEM下不起作用.
有趣的是,我不能使用我当前的方法打开进程,除非我在SYSTEM帐户下运行它,因为"客户端没有保留所需的权限",所以我无法比较启动时创建的窗口我帐户下的程序与SYSTEM帐户...
使用在我的交互式会话中运行的 IIS Express 中的 System.Diagnostic.Process.Start(),我可以执行以具有校正功能的不同用户身份运行的程序。不幸的是,这似乎不适用于非交互式会话。
指定凭据时,Process.Start 在内部调用 CreateProcessWithLogonW(CPLW)。CreateProcessWithLogonW 不能从 Windows 服务环境(如 IIS WCF 服务)调用。它只能从交互式进程(由通过 CTRL-ALT-DELETE 登录的用户启动的应用程序)中调用。-从这个 SO 答案
我需要将此站点从应用程序池帐户发布到 IIS 8。所以我按照上面引用的答案的建议 CreateProcessAsUser 。我已经使用本地安全策略设置了服务帐户和代理帐户,并按照该答案中的建议重新启动 - 服务帐户可以替换令牌,修改配额,代理帐户可以批量登录(以及作为该测试的服务)。但我不能让它在IIS快递(或控制台测试应用程序)的工作,也不IIS 8.我已经试过运行的LOGON32_LOGON_BATCH,LOGON32_LOGON_NETWORK_CLEARTEXT以及LOGON32_LOGON_SERVICE,甚至LOGON32_LOGON_INTERACTIVE。我什至给了我自己的帐户“作为服务登录”和“作为操作系统的一部分”特权,没有任何变化——所有这些都在重新启动后进行了测试。
对于所有配置,我都从 IIS Express 收到“客户端不持有所需的特权”。在服务器上,我得到相同的运行控制台应用程序。但是发布应用程序,它似乎可以很好地启动该过程,但随后我似乎遇到了权限错误。
我想知道我的帐户在本地运行时缺少哪些权限,以便我可以正确调试它们(并最终找出我遇到的任何权限错误)。有什么办法可以确定吗?无论哪种方式,如果您知道问题所在,我也希望如此!
谢谢!
我遇到了UAC的问题,并以不同的用户(诸如CreateProcessAsUser或CreateProcessWithLogonW之类的API)执行非交互式进程.
我的程序旨在执行以下操作:
1)创建一个新的Windows用户帐户(检查,正常工作)
2)以新用户帐户创建非交互式子进程(启用UAC时失败)
我的应用程序包括管理员清单,并在启用UAC时提升正确以完成步骤1.
但是第2步无法正确执行.我怀疑这是因为作为另一个用户执行的子进程不继承我的主进程(作为交互式用户执行)的提升权限.
我想知道如何解决这个问题.当UAC关闭时,我的程序正常工作.在这种情况下,我如何处理UAC或要求提升权利?
如果它有帮助,子进程需要作为另一个用户运行,以便为新用户帐户设置文件加密.
我在Windows Server 2012上运行WindowsService,它需要模拟域管理员用户(也将其添加到计算机上的本地管理员组).
系统上启用了UAC,并使用LogonType为LOGON32_LOGON_INTERACTIVE的凭据调用LogonUser,似乎返回受限令牌而不是完整令牌.
这导致我试图做的管理任务失败.
在这种情况下调用LogonUser的正确方法是什么,以便返回完整的令牌而不是受限制的令牌?
PS:我在这里遇到了一个相关的问题如何在非交互式登录下通过模拟获得提升权限(UAC)? 但它没有显示为获取完整令牌而需要进行的确切调用.