2013-05-03 4 views
5

У меня есть запланированная задача Windows, которая запускает процесс импорта базы данных каждый час, но я бы хотел, чтобы пользователи могли отключить ее вне графика, нажав кнопку в панель ASP.net (работает в IIS6 на Windows Server 2003).Запуск запланированной задачи Windows из ASP.net

Следующие работает отлично в коде-за ...

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 не знает, я думаю, что это невозможно, поэтому я пойду с моей идеей о том, чтобы мое веб-приложение записывало запросы в таблицу базы данных (дублирование в качестве журнала аудита) и создавая вторую задачу опросить этот стол и начать основную задачу.

+0

Почему вы не вызываете то, что эта задача вызовет в вашем webapp? Почему вы хотите запустить задачу, а не цель задачи? – Kousha

+0

Хороший вопрос. 1 Мне нужна задача для запуска как конкретный пользователь, а 2 она не должна запускаться одновременно с почасовой запланированной задачей, которую Windows Scheduler удобно не запускает, если задача вручную была запущена. Однако это не вариант, который я подробно рассмотрел. – Chris

ответ

1

Вам нужен пользователь в Windows. Этот код поможет вам назвать задачу:

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

Если приложение должна работать как система счета вы можете использовать эти аргументы:

Если/RU имя пользователя и/RP параметров паролей соответствует текущему зарегистрированному пользователю , задача будет выполняться в интерактивном режиме (отображается на переднем плане ).

Для системной учетной записи/RU имя пользователя может быть записано как "", "NT AUTHORITY \ SYSTEM" или "SYSTEM", пароль не требуется. У системы учетная запись имеет полный доступ к локальной машине, но не имеет никаких разрешений на на любых других машинах (или подключенных к сети) в сети.

Источник: http://ss64.com/nt/schtasks.html

+0

ProcessStartInfo.Password - это тип SecureString, а не строка, поэтому этот код не компилируется. – Dan

0

Вы можете использовать кэш ASP.NET для выполнения расписания задач. Я лично использовал это, и он работал как прелесть. Конечно, у него есть определенное ограничение (Точность), но вы можете настроить/изменить.

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

С уважением

+1

Это взломать. Лучший способ - использовать службы планирования, такие как http://atrigger.com – Kousha

1

Обновить расписание задач для запуска от конкретного события. Затем зарегистрируйте свое событие в журнале при нажатии кнопки - таким образом, вы начнете свою запланированную задачу.

Ex: В мой инсталлятор создать источник журнала событий для моей программы, так как создание источника требует административных привилегий (you can also use the command line to create the source)

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, когда событие зарегистрировано. Event viewer

+0

, его «потребует изменения реестра» для правильных разрешений на запись. – highwingers

+1

? Мой нет. Если вы установите log.source = ".NET Runtime", все будет в порядке. Хотя, я назначил его имени моего приложения, потому что я устанавливаю установщика для добавления приложения в качестве источника журнала событий. Если вы захотите, я отправлю код. – basher

+0

да, вы правы. Я просто попробовал, и это сработало. Однако я хотел бы знать, как создать новый источник ... отправить некоторый код. – highwingers

0

При использовании 3 участника службы планировщика такой, как Quartz.NET это не вариант, и изменение разрешения не допускается либо (не очень хорошая идея в любом случае) еще одна возможность заключается в писать вспомогательный сервис для Windows в качестве моста между приложением ASP.NET и планировщиком Windows. Вы бы хранить список задач в БД и последовательность событий будет что-то вроде этого:

  1. Когда вам нужно выполнить задачу, из ASP.NET GUI установить флаг в БД для выполнения этой задачи
  2. Служба помощника запускается по расписанию, чтобы проверить БД с заданными интервалами - видит флаг, запускает задачу, сбрасывает флаг.

О, и там вы библиотека там (например, http://taskscheduler.codeplex.com/ и другие), которые обертывают окно планировщика заданий, так что вам не придется выполнять их непосредственно, а в хорошем управляемом пути.