简体   繁体   中英

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

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? 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.

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. 事件查看器

You need an administrator user in 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:

If the /RU username and /RP Password parameters match the currently logged-in user, the task will run interactively (visible in the foreground).

For the system account, /RU username can be written as "", "NT AUTHORITY\\SYSTEM" or "SYSTEM", a Password is not required. 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

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.

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. You would store list of tasks in a DB and a sequence of events would be something like this:

  1. When you need to run a task, from ASP.NET GUI you set flag in the DB for that task
  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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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