Windows 服务 Process.Start 无法在网络服务帐户下工作
编辑对于任何遇到问题的人来说,这都是一个很容易解决的问题。密钥需要安装在服务帐户下。使用服务帐户登录到工作站,安装密钥,然后可以从任何在服务帐户上下文下启动它的会话运行它。问题解决了。
编辑:服务操作系统是Win 2003 编辑:启动 notepad.exe 时有效。让我相信它在调用 GnuPG 的控制台应用程序中的某个地方。
我有一个 Windows 服务,它充当将文件传入/传出网络的机制。对于其中一些进程,我想在传输发生之前或发生之后执行控制台应用程序。
我在使控制台应用程序在网络服务帐户下正确运行时遇到一些问题。
下面是问题的布局:
Windows 服务在网络服务帐户下运行,我们称之为 Company\ServiceAccount
Company\ServiceAccount
想要运行Transfer A
。在移动任何文件之前,Transfer A
需要先运行Console App A
。 Console App A
还对第三方控制台应用程序进行 shell 处理。 (原因是 - 我们希望在控制台 A 中嵌入更多业务逻辑,而不是将该代码放入服务本身)
控制台应用程序 A 调用免费的命令行 PGP 程序( GnuPG 适合任何想知道的人)。 Console App A
等待 GnuPG 完成并将一些文件移动到放置点,以便 Transfer A
可以拾取并移动它们。
应用程序代码在我的以本地系统帐户运行的工作站上运行得很好。当 Windows 服务运行时,我没有从控制台应用程序获得任何反馈。我没有收到任何访问被拒绝的错误或其他任何内容,这无助于调试此问题。
问题:
- 有什么明显的问题吗?服务帐户确实有效并且连接网络没有问题。
- 调用第三方程序时,
Console App A
是否还需要在其Process.Start()
命令中使用用户名/域/密码? - 显然,我这样做的方式可能有其他选择,但是——我应该完全放弃这个吗?我有一种感觉,它应该有效。
代码:
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
Edit 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.
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.
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.
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\ServiceAccount
Company\ServiceAccount
wants to run Transfer A
. Transfer A
needs to have Console App A
run before any files are moved. Console App A
also shells to a third-party console app program. (Reason being -- we wanted to embed more business logic in Console A
rather than putting that code in the service itself)
Console App A
calls a free command line PGP program (GnuPG for anyone wondering). Console App A
waits for GnuPG to finish and moves some files to a drop point so that Transfer A
can pick them up and move them.
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.
Questions:
- Are there any obvious problems? The service account is indeed valid and has no problem connecting to the network.
- Does
Console App A
need to also use username/domain/password in it'sProcess.Start()
command when calling the 3rd party program? - 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.
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于任何遇到问题的人来说,这都是一个很容易解决的问题。密钥需要安装在服务帐户下。使用服务帐户登录到工作站,安装密钥,然后可以从任何在服务帐户上下文下启动它的会话运行它。问题解决了。
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.
从 Windows Vista 开始,服务被明确禁止与用户会话交互,即使标记为交互。请参阅交互式服务:
如果您的任何“控制台应用程序”正在进行任何类型的用户交互,它将失败。可以这样吗?如果是,那么您不能让“控制台应用程序”从服务运行,它们必须从用户会话启动。
Starting with Windows Vista services are explicitly forbidden to interact with the user session, even when marked as interactive. See Interactive Services:
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.