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

由网友(怼)分享简介:我有一个Windows服务开发的C#和.NET 3.5在我们3域执行各种管理任务。我有在具有什么这个服务做必要的权利/权限的每个域管理员帐户。I have a Windows Service developed in C# and .NET 3.5 to perform various administrative...

我有一个Windows服务开发的C#和.NET 3.5在我们3域执行各种管理任务。我有在具有什么这个服务做必要的权利/权限的每个域管理员帐户。

I have a Windows Service developed in C# and .NET 3.5 to perform various administrative tasks throughout our 3 domains. I've got an admin account in each domain that has the necessary rights/permissions for what this service is doing.

有关所有广告互动,我可以使用正确的用户名/密码域绑定到AD和一切都很好。不过,我有现在需要启动一个外部程序(的Robocopy)来完成一些工作,我无法找到任何code实例的任何地方做这在.NET 3.5。

For all the AD interactions, I can bind to AD using the correct username/password for the domain and all is good. However, I have a need now to launch an external process (robocopy) to perform some work and I cannot find any code examples anywhere for doing this in .NET 3.5.

我需要做的是利用备用凭据在一个隐藏的窗口推出的Robocopy,捕捉到标准输出,所以我有一个日志什么是真正做的,并捕获退出code,所以我知道它是成功的

What I need to do is launch robocopy using alternate credentials in a hidden window, capture the standard output so I have a log of what was actually done, and capture the exit code so I can tell if it was successful.

我发现从的 K。斯科特·艾伦的博客(见的好code上市的最后几个评论),它扩展了的System.Diagnostics.Process对象并调用Win32 API函数CreateProcessAsUserW。然而,code不会由于.NET 2.0的一些API的变化工作。从那里使用反射调用处理对象的私人SetProcessHandle函数引用的博客最后一个注释使用code段会导致访问被拒绝错误,当我尝试与流程交互(将其杀死或获得退出code)。

I found some old .NET 1.1 code from K. Scott Allen's blog (see the last few comments for a good code listing) that extends the System.Diagnostics.Process object and calls the Win32 API function CreateProcessAsUserW. However, the code doesn't work due to some API changes in .NET 2.0. Using the code snippet from the last comment on the referenced blog where it is using reflection to call the private SetProcessHandle function of the Process object causes Access Denied errors when I try to interact with the process (to kill it or get exit code).

有没有人对如何做到这一点的好例子?

Does anyone have a good example of how to accomplish this?

编辑:内置.NET过程和的ProcessStartInfo API允许您指定备用凭据,但当你做什么,它想要创建一个可见的窗口运行时,它失败(即使您指定CreateNoWindow或WindowStyle隐藏) Windows服务。所以,这些都不是这种应用的一个选项。模拟也不管用,因为当外部进程启动时,它使用父进程的凭据,而不是模拟凭据。

The built-in .NET Process and ProcessStartInfo API does allow you to specify alternate credentials but when you do, it wants to create a visible window (even if you specify CreateNoWindow or WindowStyle Hidden) which fails when running as a Windows Service. So those are not an option for this application. Impersonation doesn't work either since when the external process is launched, it uses the credentials of the parent process, not the impersonated credentials.

解决方案:里德指出以下,P / Invoke的使用的Win32 API函数应该让你做到这一点。我最终会稍有不同的路线,使用的是旧免费NT4工具称为RunProcess ,允许您指定用户名/密码在命令行上。它的工作在Vista和2K3也工作正常时,由作为本地系统运行Windows服务启动。

SOLUTION: As Reed pointed out below, P/Invoke using one of the Win32 API functions should allow you to make this happen. I ended up going a slightly different route using an old freeware NT4 utility called RunProcess that allows you to specify a username/password on the command line. It worked on Vista and 2k3 and also worked correctly when launched by a windows service running as Local System.

推荐答案

我想你想看看:

的ProcessStartInfo

这提供了根据不同的用户具有不同的凭据启动进程。NET唯一途径。没有更多的需要在Win32 API。

That provides a .NET only way to start a process under a different user with different credentials. No more need for the Win32 API.

---编辑---

其他替代可能是使用在P /调用如这里(看注,倒数第一),或者更有可能,使用P / Invoke与 CreateProcessWithLogonW 。

Other alternatives might be to use the P/Invoke as specified here (look at the note at the bottom first) or more likely, using P/Invoke with CreateProcessWithLogonW.

阅读全文

相关推荐

最新文章