我尝试从Web应用程序调用.exe文件。但是我想要由用户调用的文件,该文件由网站的Windows身份验证非个性化。
Process process = new Process();
try
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = ConfigData.PVDToBudgetDBexePath;
process.StartInfo.CreateNoWindow = false;
process.Start();
log.Info("Process started by " + WindowsIdentity.GetCurrent().Name + " with ID: " + process.Id);
process.WaitForExit();
log.Info("After WaitForExit Process ID: " + process.Id);
}
catch (Exception ex)
{
log.Error("Error executing file with message " + ex.Message);
}
两个信息日志文本都已正确记录。没有发生错误。但是被调用的程序不执行任何操作。没有日志记录,没有写入数据库。用户对文件具有可执行权限。
当我从开发服务器调用相同的代码时,它工作正常。
我使用 .Net 4.5 和 IIS 7我发现有关此主题的帖子仅适用于非常旧版本的.Net和IIS,这对我无济于事。
我做错了什么?或者我怎样才能找出出了什么问题?
非常感谢,
编辑:为了更好地阐明我的意图:我有这个(自制的)exe文件,可以将Excel工作表中的数据导入数据库。这需要一些时间。在这样做的同时,它会将其进度和log4net也记录到数据库中。我想要一个UI(Web应用程序)是用户可以触发导入的。在此 UI 上还有一个 ajax 进度条,显示从数据库中的日志表中导入 takten 的进度。
我希望此导入过程最多同时运行一个实例。所以我有一个函数来检查进程是否仍在运行。如果是这样,则不允许启动另一个进程。如果没有,您可以重新启动它。
private bool IsRunning(string name)
{
Process[] processlist = Process.GetProcesses();
if (Process.GetProcessesByName(name).Length > 0 )
{
return true;
}
else
{
return false;
}
}
我现在通过TimeScheduler启动exe文件解决了这个问题。
路径 = 文件EXE文件的路径
参数 = 用于启动 exe 文件的参数
using Microsoft.Win32.TaskScheduler;
using (TaskService taskService = new TaskService())
{
var taskDefinition = taskService.NewTask();
taskDefinition.RegistrationInfo.Author = WindowsIdentity.GetCurrent().Name;
taskDefinition.RegistrationInfo.Description = "Runs exe file";
var action = new ExecAction(path, arguments);
taskDefinition.Actions.Add(action);
taskService.RootFolder.RegisterTaskDefinition("NameOfTask", taskDefinition);
//get task:
var task = taskService.RootFolder.GetTasks().Where(a => a.Name == "NameOfTask").FirstOrDefault();
try
{
task.Run();
}
catch (Exception ex)
{
log.Error("Error starting task in TaskScheduler with message: " + ex.Message);
}
}
如果您所说的开发服务器是指由Visual Studio启动的Web服务器,那么这将为您提供一个错误的测试用例,因为该服务器由Visual Studio启动并使用您的Windows帐户运行,而标准配置的IIS不是在"用户"帐户下运行,而是在非常有限的系统帐户下运行(幸运的是!!即使用户使用您网站的域帐户登录,IIS 进程也不会在此帐户下运行(无论如何这都没有意义)。这就是为什么此代码不会在 IIS 中运行,而是在开发服务器中运行的原因。即使您启动 exe,它也将使用 IIS 的系统帐户运行,因为您没有提供任何帐户,这是一个有限的帐户,它将再次以不同于您预期的方式运行 exe。
如果您真的想这样做,您将不得不使用模拟,但您必须启动该过程"模拟"登录网站的用户,支持用于登录的用户帐户在这一点上甚至有意义。 例如,如果它是一个域帐户,这可能会起作用,但是如果您使用某种其他类型的身份验证, 与窗体身份验证一样,这在操作系统级别没有任何意义,因此不能将这些凭据用于 IIS 中的模拟。
根据我的经验,我已经这样做过几次,在IIS中模拟总是一件坏事,并且总是会产生问题,顺便说一下,启动命令行进程也是如此。幸运的是,当您考虑它时,总有一个更好/替代的解决方案。此外,等待进程在代码中结束并不是一个好的做法。如果进程阻塞怎么办?它将阻止网站。
幸运的是,当您考虑它时,总有一个更好/替代的解决方案。这里更好/可能的解决方案是使用消息队列,例如,您只需推送消息以执行任务,另一端是处理消息的应用程序,然后可能会使用此命令行工具。该应用程序可以在所需的任何用户帐户下运行,而不必让 IIS 在其他帐户下运行。稍后您当然必须回来查找操作的结果,但这可以使用网站后台的回调来完成。虽然这个解决方案比你想做的要大一点,但它几乎在每个领域都会有更好的结果(网站的响应能力、可维护性、可扩展性,..唯一更糟糕的是你需要的代码行,但这很少是一个需要考虑的有效因素
如果您自己编写用于 excel 处理的应用程序,则可以将数据库中的表用作某种队列,而不是使用消息总线。然后,您的 Web 应用程序只需在该表中添加包含流程的所有必要信息的行,状态和进度就是其中之一。扩展您的处理应用程序以持续监视此表,一旦它检测到新记录,它就可以开始执行必要的任务并相应地更新数据库进度、状态和最终结果)。这避免了消息传递子系统,将同样出色地工作,并且将避免您不得不启动具有模拟的进程,这是一开始的邪恶事情。
您可以将 excel 进程修改为 Windows 服务,以便它连续运行并与系统一起启动,但是,如果您不想这样做,还有一些工具可以将任何命令行应用程序作为 Windows 服务运行)。
这种技术比模拟容易得多,并允许您的网站在其受保护的环境中运行