Windows 服务 Process.Start 在网络服务帐户下不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3481895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:02:14  来源:igfitidea点击:

Windows service Process.Start not working under network service account

c#windowswindows-servicesprocess

提问by Bryan Crosby

EditFor anyone having an issue, it turns out to be, as usual, a simple problem to solve. The keys need to be installed under the service account. Log on to the workstation under the service account, install the keys, and then it can be run from any session that would be launching it under the service account context. Problem solved.

编辑对于任何有问题的人来说,像往常一样,这是一个需要解决的简单问题。密钥需要安装在服务帐户下。使用服务帐户登录到工作站,安装密钥,然后可以从将在服务帐户上下文下启动它的任何会话运行它。问题解决了。

Edit: Service OS is Win 2003 Edit: Works when launching notepad.exe. Leading me to believe it's somewhere in the console app calling GnuPG.

编辑:服务操作系统是 Win 2003 编辑:在启动 notepad.exe 时工作。让我相信它在调用 GnuPG 的控制台应用程序中的某个地方。

I have a windows service that acts as a mechanism to transfer files in/out of the network. For some of these processes, I would like to execute a console app prior to the transfer occurring, or, after it occurs.

我有一个 Windows 服务,它充当将文件传入/传出网络的机制。对于其中一些进程,我想在传输发生之前或之后执行一个控制台应用程序。

I am having some issues getting the console applications to run correctly under a network service account.

我在使控制台应用程序在网络服务帐户下正确运行时遇到了一些问题。

Here is a layout of the problem:

这是问题的布局:

Windows service runs under a network service account, let's call it Company\ServiceAccountCompany\ServiceAccountwants to run Transfer A. Transfer Aneeds to have Console App Arun before any files are moved. Console App Aalso shells to a third-party console app program. (Reason being -- we wanted to embed more business logic in Console Arather than putting that code in the service itself)

Windows 服务运行在一个网络服务帐户下,我们称之为它Company\ServiceAccountCompany\ServiceAccount想运行Transfer ATransfer A需要Console App A在移动任何文件之前运行。 Console App A也外壳到第三方控制台应用程序。(原因是——我们想嵌入更多的业务逻辑,Console A而不是将该代码放在服务本身中)

Console App Acalls a free command line PGP program (GnuPG for anyone wondering). Console App Awaits for GnuPG to finish and moves some files to a drop point so that Transfer Acan pick them up and move them.

Console App A调用一个免费的命令行 PGP 程序(GnuPG 对于任何想知道的人)。 Console App A等待 GnuPG 完成并将一些文件移动到放置点,以便Transfer A可以拾取并移动它们。

The application code runs just fine on my workstation running under the local system account. When the Windows service runs, I don't get any feedback from the Console application. I don't get any access denied errors or anything else, which isn't helping trying to debug this.

应用程序代码在我在本地系统帐户下运行的工作站上运行得很好。当 Windows 服务运行时,我没有从控制台应用程序得到任何反馈。我没有收到任何拒绝访问错误或其他任何信息,这无助于调试此问题。

Questions:

问题:

  1. Are there any obvious problems? The service account is indeed valid and has no problem connecting to the network.
  2. Does Console App Aneed to also use username/domain/password in it's Process.Start()command when calling the 3rd party program?
  3. Obviously there could be alternatives to the way I am doing this but -- should I abandon this completely? I have a feeling it should work.
  1. 有什么明显的问题吗?服务帐户确实有效,并且连接到网络没有问题。
  2. 调用第3方程序时是否Console App A还需要在其Process.Start()命令中使用用户名/域/密码?
  3. 显然,我这样做的方式可能有其他选择,但是 - 我应该完全放弃吗?我有一种感觉它应该起作用。

Code:

代码:

      System.Diagnostics.Process process = null;
        System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(executable, args);

        string pwd = "mypassword"; //edited for security
        System.Security.SecureString securePwd = new System.Security.SecureString();

        foreach (char c in pwd)
            securePwd.AppendChar(c);

        try
        {
            psi.UseShellExecute = false;
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.CreateNoWindow = true;
            psi.ErrorDialog = false;
            psi.Password = securePwd;
            psi.UserName = "myserviceaccount"; //edited for security
            psi.Domain = "MyCompanyDomain"; //edited for security
            process = System.Diagnostics.Process.Start(psi);
            //Wait for the process to finish
            process.WaitForExit();
            process.Close();
        }
        catch (System.InvalidOperationException iox) { } //handle
        catch (System.ArgumentException ax) { } //handle
        catch (System.ComponentModel.Win32Exception wx) { } //handle 
        catch (System.IO.FileNotFoundException fnfx) { } //handle

回答by Bryan Crosby

For anyone having an issue, it turns out to be, as usual, a simple problem to solve. The keys need to be installed under the service account. Log on to the workstation under the service account, install the keys, and then it can be run from any session that would be launching it under the service account context. Problem solved.

对于任何遇到问题的人来说,结果证明它像往常一样是一个需要解决的简单问题。密钥需要安装在服务帐户下。使用服务帐户登录到工作站,安装密钥,然后可以从将在服务帐户上下文下启动它的任何会话运行它。问题解决了。

回答by Remus Rusanu

Starting with Windows Vista services are explicitly forbidden to interact with the user session, even when marked as interactive. See Interactive Services:

从 Windows Vista 开始,明确禁止服务与用户会话交互,即使标记为交互。请参阅交互式服务

ImportantServices cannot directly interact with a user as of Windows Vista. Therefore, the techniques mentioned in the section titled Using an Interactive Service should not be used in new code.

重要服务不能直接与 Windows Vista 的用户交互。因此,不应在新代码中使用标题为使用交互式服务的部分中提到的技术。

If any of your 'console app* are doing any sort of user interaction, it will fail. Can this be the case? If yes, then you cannot have your 'console apps' run from a service, they will have to be launched from a user session.

如果您的任何“控制台应用程序*”正在进行任何类型的用户交互,它将失败。可以这样吗?如果是,那么您不能让您的“控制台应用程序”从服务中运行,它们必须从用户会话中启动。