我有一个ASP.NET MVC4网站,我试图在该网站上执行服务器上的进程。代码如下:
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = ExeLocation,
Arguments = string.Format("\"{0}\"{1}", ScriptLocation, Arguments),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
WorkingDirectory = AppDir,
CreateNoWindow = true,
UserName = ExeUsername,
Password = ExePassword,
Domain = ExeDomain
};
using (Process process = Process.Start(startInfo))
{
using (StreamReader reader = process.StandardOutput)
{
output = reader.ReadToEnd();
}
using (StreamReader reader = process.StandardError)
{
error = reader.ReadToEnd();
}
process.WaitForExit();
if (process.ExitCode != 0)
{
throw new Exception(string.IsNullOrEmpty(output) ? error : output);
}
}
这在Visual Studio中的本地计算机上正常运行,但是当我将其部署到服务器(W2K12)时,出现以下错误:
Access is denied
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
我在服务器的管理员和 IIS_IUSRS 组中都有ExeUsername
引用的帐户。
应用程序池以另一个帐户(因此需要分配一个特定的帐户来运行该进程)运行,该帐户也是服务器上Administrators和IIS_IUSRS的成员。
登录服务器并以ExeUsername
身份运行命令提示符时,我能够执行该过程,因此问题必须与从IIS执行有关。
还有什么可能阻止此访问?
答案 0 :(得分:0)
如果您拥有域,请小心使用 domain \ username 作为用户名
并访问部署文件夹。
答案 1 :(得分:0)
我会尝试另一种方法。首先模拟一个自定义用户(有权运行命令的用户),然后在模拟用户的上下文中启动一个进程:
SafeAccessTokenHandle safeAccessTokenHandle;
bool returnValue = LogonUser(ExeUsername, ExeDomain, ExePassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeAccessTokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
WindowsIdentity.RunImpersonated(safeAccessTokenHandle, () =>
{
var startInfo = new ProcessStartInfo()
{
FileName = ExeLocation,
Arguments = string.Format("\"{0}\"{1}", ScriptLocation, Arguments),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
WorkingDirectory = AppDir,
CreateNoWindow = true,
UserName = ExeUsername,
Password = ExePassword,
Domain = ExeDomain
};
using (Process process = Process.Start(startInfo))
{
using (StreamReader reader = process.StandardOutput)
{
output = reader.ReadToEnd();
}
using (StreamReader reader = process.StandardError)
{
error = reader.ReadToEnd();
}
process.WaitForExit();
if (process.ExitCode != 0)
{
throw new Exception(string.IsNullOrEmpty(output) ? error : output);
}
}
);
LogonUser方法如下所示:
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain,
String lpszPassword, int dwLogonType, int dwLogonProvider,
out SafeAccessTokenHandle phToken);
有关在.NET中模拟的更多信息,请访问:https://docs.microsoft.com/en-gb/dotnet/api/system.security.principal.windowsidentity.runimpersonated?view=netframework-4.7.2
答案 2 :(得分:0)
也许使用此功能对您有帮助。
ProcessStartInfo startInfo = new ProcessStartInfo()
{
//...
UseShellExecute = true,
Verb = "runas"
};
如果遇到错误,也可以检查this。