简体   繁体   English

从ASP.net运行Windows计划任务

[英]Running a Windows Scheduled Task from ASP.net

I have a Windows scheduled task that runs a database import process every hour, but I'd like users to be able to kick it off out-of-schedule by hitting a button in an ASP.net dashboard (running in IIS6 on Windows Server 2003). 我有一个Windows计划任务,每小时运行一次数据库导入过程,但我希望用户能够通过点击ASP.net仪表板中的按钮(在Windows Server上的IIS6中运行)将其打开。 2003)。

The following works perfectly in code-behind ... 以下在代码隐藏中完美运行...

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();

... but only if the application pool identity is set to Local System (not ideal!). ...但仅当应用程序池标识设置为本地系统时(不理想!)。 If I leave it as Network Service, the task does not start. 如果我将其保留为网络服务,则任务无法启动。 So it is presumably a permissions issue. 所以它可能是一个权限问题。

Is there a way ASP.net can kick off a scheduled task on the server without running the application as Local System? ASP.net是否可以在服务器上启动计划任务而无需将应用程序作为本地系统运行? If not, what good alternatives are there? 如果没有,有什么好的替代品?

Update: if nobody on SO knows, I guess it is not possible so I will go with my idea of having my web application write requests to a database table (doubling as an audit log) and creating a second task to poll that table and kick off the main task. 更新:如果SO上没有人知道,我想这是不可能的,所以我会想到让我的Web应用程序将请求写入数据库表(加倍作为审计日志)并创建第二个任务来轮询该表并踢关闭主要任务。

Update your schedule task to trigger off a specific event. 更新计划任务以触发特定事件。 Then have your website log that event when the button is clicked - thus starting your scheduled task. 然后让您的网站在单击按钮时记录该事件 - 从而开始您的计划任务。

Ex: In my installer I create an event log source for my program, since creating the source requires administrative privileges ( you can also use the command line to create the source ) 例如:在我的安装程序中,我为我的程序创建了一个事件日志源,因为创建源需要管理权限( 您也可以使用命令行创建源

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

Then in my application, I create an event log entry when the button is clicked. 然后在我的应用程序中,单击按钮时创建一个事件日志条目。

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) 
    {
        ...   
    }
}

And the task scheduler set to open MyOtherApp when the event is logged. 并且任务计划程序设置为在记录事件时打开MyOtherApp。 事件查看器

You need an administrator user in windows. 您需要Windows中的管理员用户。 This code will help you to call the task: 此代码将帮助您调用任务:

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();

If your application needs to run as SYSTEM Account you can use this arguments: 如果您的应用程序需要以SYSTEM帐户身份运行,则可以使用以下参数:

If the /RU username and /RP Password parameters match the currently logged-in user, the task will run interactively (visible in the foreground). 如果/ RU用户名和/ RP密码参数与当前登录的用户匹配,则任务将以交互方式运行(在前台可见)。

For the system account, /RU username can be written as "", "NT AUTHORITY\\SYSTEM" or "SYSTEM", a Password is not required. 对于系统帐户,/ RU用户名可以写为“”,“NT AUTHORITY \\ SYSTEM”或“SYSTEM”,不需要密码。 The system account has full access to the local machine but has no permissions on any other machines (or mapped drives) across the Network. 系统帐户具有对本地计算机的完全访问权限,但对网络上的任何其他计算机(或映射驱动器)没有权限。

Source: http://ss64.com/nt/schtasks.html 资料来源: http//ss64.com/nt/schtasks.html

You can utilize the cache of ASP.NET to run schedule tasks. 您可以利用ASP.NET的缓存来运行计划任务。 I personally used this and it worked like charm. 我亲自使用它,它的功效就像魅力一样。 Ofcourse it has some limitation (Accuracy) but you can adjust/change. 当然它有一些限制(准确性),但你可以调整/改变。

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

Regards 问候

If using a 3rd party scheduler service such as Quartz.NET is not an option, and changing permissions is not allowed either (not a good idea in any case) another possibility is to to write a helper Windows service as a bridge between ASP.NET application and Windows scheduler. 如果使用第三方调度程序服务(如Quartz.NET )不是一个选项,并且不允许更改权限(在任何情况下都不是一个好主意)另一种可能性是将帮助程序Windows服务编写为ASP.NET之间的桥梁应用程序和Windows调度程序。 You would store list of tasks in a DB and a sequence of events would be something like this: 您可以在DB中存储任务列表,事件序列如下:

  1. When you need to run a task, from ASP.NET GUI you set flag in the DB for that task 当您需要运行任务时,从ASP.NET GUI中为该任务在DB中设置标志
  2. Helper service runs on schedule to check the DB at given intervals - sees the flag, starts the task, reset the flag. 帮助程序服务按计划运行,以给定的时间间隔检查数据库 - 查看标志,启动任务,重置标志。

Oh and there're libraries out there (eg http://taskscheduler.codeplex.com/ and others) that wrap Window Task Scheduler, so you don't have to execute them directly, but rather in a nice managed way. 哦,还有那些包含Window Task Scheduler的库(例如http://taskscheduler.codeplex.com/和其他),所以你不必直接执行它们,而是以一种很好的管理方式执行它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM