7

我有一个 Windows 计划任务,它每小时运行一个数据库导入过程,但我希望用户能够通过点击 ASP.net 仪表板中的按钮(在 Windows Server 上的 IIS6 中运行2003)。

以下代码在代码隐藏中完美运行......

var proc = new Process
            {
                StartInfo =
                    {
                        UseShellExecute = false,
                        FileName = @"C:\Windows\System32\schtasks.exe",
                        Arguments = "/run /tn Loader",
                        RedirectStandardError = true,
                        RedirectStandardOutput = true,
                        CreateNoWindow = true
                    }
            };
proc.Start();
proc.WaitForExit();

...但前提是应用程序池标识设置为本地系统(不理想!)。如果我将其保留为网络服务,则任务不会启动。所以这可能是一个权限问题。

有没有办法 ASP.net 可以在服务器上启动计划任务而不将应用程序作为本地系统运行?如果没有,有什么好的选择?

更新:如果 SO 上没有人知道,我想这是不可能的,所以我会按照我的想法让我的 Web 应用程序将请求写入数据库表(作为审计日志加倍)并创建第二个任务来轮询该表并启动脱离主线任务。

4

4 回答 4

5

更新您的计划任务以触发特定事件。然后让您的网站在单击按钮时记录该事件 - 从而启动您的计划任务。

例如:在我的安装程序中,我为我的程序创建了一个事件日志源,因为创建源需要管理权限(您也可以使用命令行来创建源

  if (EventLog.SourceExists("MyApp"))
  {
      EventLog.CreateEventSource("MyApp", "Application");
  }

然后在我的应用程序中,单击按钮时创建一个事件日志条目。

private void btnOpenOtherApp_Click (object sender, EventArgs e) 
{
    try 
    {
        var log = new EventLog
        {
            Source = "MyApp"
        };
        log.WriteEntry("Start MyOtherApp", EventLogEntryType.Information, 1337);
    } 
    catch (Exception ex) 
    {
        ...   
    }
}

并且任务计划程序设置为在记录事件时打开 MyOtherApp。 事件查看器

于 2013-11-06T16:16:23.417 回答
1

您需要在 windows 中的管理员用户。此代码将帮助您调用任务:

var securePass = new System.Security.SecureString();
foreach (char c in "my_password")
{
    pass.AppendChar(c);
}

var proc = new Process
{
    StartInfo =
    {
        UseShellExecute = false,
        FileName = @"C:\Windows\System32\schtasks.exe",
        Arguments = "/run /tn Loader",
        UserName = "myAdminUser", //NEW
        Password = securePass, //NEW
        RedirectStandardError = true,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    }
};
proc.Start();
proc.WaitForExit();

如果您的应用程序需要以 SYSTEM 帐户运行,您可以使用以下参数:

如果 /RU 用户名和 /RP 密码参数与当前登录的用户匹配,则任务将以交互方式运行(在前台可见)。

对于系统帐户,/RU 用户名可以写为“”、“NT AUTHORITY\SYSTEM”或“SYSTEM”,不需要密码。系统帐户对本地计算机具有完全访问权限,但对网络上的任何其他计算机(或映射的驱动器)没有权限。

来源:http ://ss64.com/nt/schtasks.html

于 2013-08-27T11:01:22.933 回答
0

如果不能选择使用诸如Quartz.NET 之类的 3rd 方调度程序服务,并且也不允许更改权限(在任何情况下都不是一个好主意),另一种可能性是编写一个辅助 Windows 服务作为 ASP.NET 之间的桥梁应用程序和 Windows 调度程序。您将在数据库中存储任务列表,并且一系列事件将是这样的:

  1. 当您需要运行任务时,从 ASP.NET GUI 中为该任务在数据库中设置标志
  2. 助手服务按计划运行,以给定的时间间隔检查数据库 - 看到标志,启动任务,重置标志。

哦,还有一些库(例如http://taskscheduler.codeplex.com/和其他)包装了 Window Task Scheduler,因此您不必直接执行它们,而是以一种很好的托管方式。

于 2013-11-06T16:29:25.903 回答
0

You can utilize the cache of ASP.NET to run schedule tasks. I personally used this and it worked like charm. Ofcourse it has some limitation (Accuracy) but you can adjust/change.

https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

Regards

于 2013-08-27T11:16:03.817 回答