C# 和 .NET 3.5 - 如何使用不同的凭据启动进程,使用隐藏窗口,并能够捕获标准输出和退出代码?

标签 c# .net .net-3.5 process credentials

我有一个用 C# 和 .NET 3.5 开发的 Windows 服务,用于在我们的 3 个域中执行各种管理任务。我在每个域中都有一个管理员帐户,该帐户具有执行此服务所必需的权利/权限。

对于所有 AD 交互,我可以使用域的正确用户名/密码绑定(bind)到 AD,一切都很好。但是,我现在需要启动一个外部进程 (robocopy) 来执行一些工作,但我在 .NET 3.5 中找不到任何代码示例来执行此操作。

我需要做的是在隐藏窗口中使用备用凭据启动 robocopy,捕获标准输出以便记录实际执行的操作,并捕获退出代码以便判断它是否成功。

我从 K. Scott Allen's blog 中找到了一些旧的 .NET 1.1 代码(请参阅最后几条评论以获得良好的代码 list )扩展 System.Diagnostics.Process 对象并调用 Win32 API 函数 CreateProcessAsUserW。但是,由于 .NET 2.0 中的一些 API 更改,代码无法正常工作。使用引用博客上最后一条评论中的代码片段,其中使用反射调用 Process 对象的私有(private) SetProcessHandle 函数,当我尝试与该进程交互(终止它或获取退出代码)时,会导致访问被拒绝错误。

有没有人有一个很好的例子来说明如何做到这一点?

编辑:内置的 .NET Process 和 ProcessStartInfo API 确实允许您指定备用凭据,但是当您这样做时,它想要创建一个可见窗口(即使您指定了 CreateNoWindow 或 WindowStyle Hidden),当作为Windows 服务。所以那些不是这个应用程序的选项。模拟也不起作用,因为启动外部进程时,它使用父进程的凭据,而不是模拟的凭据。

解决方案:正如 Reed 在下面指出的那样,使用 Win32 API 函数之一的 P/Invoke 应该可以让您实现这一点。我最终使用旧的 freeware NT4 utility called RunProcess 走了一条稍微不同的路线。允许您在命令行上指定用户名/密码。它适用于 Vista 和 2k3,并且在由作为本地系统运行的 Windows 服务启动时也能正常工作。

最佳答案

我想你想看看:

ProcessStartInfo

这提供了一种仅用于 .NET 的方式来在具有不同凭据的不同用户下启动进程。不再需要 Win32 API。

--- 编辑 ---

其他替代方法可能是使用指定的 P/Invoke here (首先查看底部的注释)或者更可能的是,将 P/Invoke 与 CreateProcessWithLogonW 结合使用.

关于C# 和 .NET 3.5 - 如何使用不同的凭据启动进程,使用隐藏窗口,并能够捕获标准输出和退出代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/643723/

相关文章:

c# - C#对几个字符串使用相同的变量

c# - 检查通用方法中包含哪些类型的枚举

c# - WebBrowser 控件 : window. 外部访问数组

.net - 为什么在 .NET 中复制字符串?

C# 如何确保用户提供线程安全对象来运行

c# - 新类型由 decimal 和 double 组成

c# - 创建用于数据库的哈希码(即不使用 GetHashCode)

.net - 如何在 .NET MySqlCommand 中使用 MySql 用户定义变量?

c# - 将方法作为参数传递

c# - 开始现代游戏编程和应用程序编程的最佳方式是什么?