我在使用PowerShell的Start-Process调用时遇到了一种奇怪的行为。
这是调用的代码:
$process = start-process `
"C:\somepath\MyBinary.exe" `
-PassThru `
-Credential $defaultCredential `
-Wait `
-WorkingDirectory "C:\somepath" `
-LoadUserProfile
if ($process.ExitCode -ne 0)
{
#do something
}
这个调用总是返回退出代码-1073741502
。
经过快速搜索,发现该退出代码似乎与程序无法加载所需的dll(也称为STATUS_DLL_INIT_FAILED
)相关。
当我没有使用-Credential $credential
时,程序可以正常运行。
为了分离问题,我手动使用目标凭据在提示符中启动了some.exe
,它可以平稳运行。
因此,问题似乎只来自start-process cmdlet有效地启动进程的方式。
我找到了一些潜在的解决方案,但尝试应用没有成功:link和link。
你有什么想法吗?
编辑1:
我运行了一个proc mon来监视直接启动或通过powershell脚本启动程序的活动。问题似乎出现在加载kernelbase.dll
时。
本地procmon转储(工作):
9:06:35.3837439 AM MyBinary.exe 2620 Load Image C:\Windows\SysWOW64\kernelbase.dll SUCCESS Image Base: 0x76270000, Image Size: 0x47000
9:06:35.4317417 AM MyBinary.exe 2620 RegOpenKey HKLM\System\CurrentControlSet\Control\Nls\Sorting\Versions REPARSE Desired Access: Read
9:06:35.4317751 AM MyBinary.exe 2620 RegOpenKey HKLM\System\CurrentControlSet\Control\Nls\Sorting\Versions SUCCESS Desired Access: Read
9:06:35.4318016 AM MyBinary.exe 2620 RegSetInfoKey HKLM\System\CurrentControlSet\Control\Nls\Sorting\Versions SUCCESS KeySetInformationClass: KeySetHandleTagsInformation, Length: 0
9:06:35.4318152 AM MyBinary.exe 2620 RegQueryValue HKLM\System\CurrentControlSet\Control\Nls\Sorting\Versions\(Default) SUCCESS Type: REG_SZ, Length: 36, Data: 00060101.00060101
...
Powershell procmon(失败,查看线程退出和进程退出代码-1073741502
):
9:35:07.9455191 AM MyBinary.exe 2276 Load Image C:\Windows\SysWOW64\kernelbase.dll SUCCESS Image Base: 0x76270000, Image Size: 0x47000
9:35:07.9537146 AM MyBinary.exe 2276 Thread Exit SUCCESS Thread ID: 5112, User Time: 0.0000000, Kernel Time: 0.0000000
9:35:07.9537386 AM MyBinary.exe 2276 QueryNameInformationFile C:\Windows\System32\apisetschema.dll SUCCESS Name: \Windows\System32\apisetschema.dll
9:35:07.9537686 AM MyBinary.exe 2276 QueryNameInformationFile C:\somepath\MyBinary\MyBinary.exe SUCCESS Name: \somepath\MyBinary\MyBinary.exe
9:35:07.9537914 AM MyBinary.exe 2276 QueryNameInformationFile C:\Windows\System32\wow64cpu.dll SUCCESS Name: \Windows\System32\wow64cpu.dll
9:35:07.9538134 AM MyBinary.exe 2276 QueryNameInformationFile C:\Windows\System32\wow64win.dll SUCCESS Name: \Windows\System32\wow64win.dll
9:35:07.9538349 AM MyBinary.exe 2276 QueryNameInformationFile C:\Windows\System32\wow64.dll SUCCESS Name: \Windows\System32\wow64.dll
9:35:07.9538579 AM MyBinary.exe 2276 QueryNameInformationFile C:\Windows\System32\ntdll.dll SUCCESS Name: \Windows\System32\ntdll.dll
9:35:07.9538796 AM MyBinary.exe 2276 QueryNameInformationFile C:\Windows\SysWOW64\ntdll.dll SUCCESS Name: \Windows\SysWOW64\ntdll.dll
9:35:07.9539425 AM MyBinary.exe 2276 Process Exit SUCCESS Exit Status: -1073741502, User Time: 0.0000000 seconds, Kernel Time: 0.0000000 seconds, Private Bytes: 339,968, Peak Private Bytes: 401,408, Working Set: 1,523,712, Peak Working Set: 1,826,816
编辑 2:
我应该提到powershell脚本是从服务中运行的(它是一个bamboo服务代理)。我刚刚发现这个线程说:
当指定凭据时,Process.Start内部调用CreateProcessWithLogonW(CPLW)。不能从Windows服务环境(例如IIS WCF服务)中调用CreateProcessWithLogonW。它只能从交互式进程(通过CTRL-ALT-DELETE登录的用户启动的应用程序)中调用。
我的猜测是powershell start-process调用正在使用CreateProcessWithLogonW
...
编辑 3:
我的服务是以自定义用户身份运行的(因为我无法从System中模拟),所以根据这个链接进行了测试。我测试确保启用了“允许服务与桌面交互”。因为它仅适用于非自定义帐户,所以我通过手动更改HKLM\System\CurrentControlSet\Services\%myservice%
类型键来在注册表上设置它(如此处和此处所述)。