Search code examples
c#windowsscheduled-tasksazure-service-fabrictaskscheduler

Task Scheduler Not Running task with Network Path


I am working in a test development environment and I am creating a task in task scheduler that is using a remote network location to access an executable file. Although in my scenario that network address is of my own machine. Like this

\\MyComputerName\FolderOnMyPC\application.exe

Now I have given proper sharing access to the folder and I can access the executable via Explorer but when I create a task in Task Scheduler I am unable to run it. Although the task runs fine with the local disk path like this

D:\FolderOnMyPC\application.exe

I have tried looking into this over the Internet but I am unable to find any workaround or the reason it is happening as I have given every possible access to the folders even in

System32/Tasks

There are also some arguments that are specified in the arguments section of the Task Scheduler

Edited

I am sharing the code for executing the task.

public Task<int> Launch(string Path, string iniFilePath)
        {
            try
            {
                TaskService taskService = new TaskService();

                const string TaskName = "LaunchTask";
                if (taskService.FindTask(TaskName) != null)
                {
                    var task = taskService.FindTask(TaskName);
                }

                iniFilePath = "\"" + iniFilePath + "\"";
                string completeArgument = "/portable /skipupdate " + iniFilePath;
                TaskDefinition taskDefinition = taskService.NewTask();            
                taskDefinition.Principal.LogonType = TaskLogonType.S4U;
                taskDefinition.Actions.Add(new ExecAction(mt4Path, completeArgument, null));                          
                taskDefinition.Settings.Hidden = false;
                Microsoft.Win32.TaskScheduler.Task mtTask = taskService.RootFolder.RegisterTaskDefinition(TaskName, taskDefinition);
                RunningTask runningMT4 = mtTask.Run();
                int processIdMT = (int)runningMT.EnginePID;
                mt4Task.Folder.DeleteTask(mtTask.Name);
                return System.Threading.Tasks.Task.FromResult(processIdMT);
            }
            catch
            {
                throw;
            }
        }

Some extra information about the project is that I am working on a Service Fabric Project and its using it as its Service.


Solution

  • I was trying to look into the other direction probably although I may have found a solution that can very much be a workaround but hope it helps someone else like me. The problem was in this line

    taskDefinition.Principal.LogonType = TaskLogonType.S4U;
    

    Now seeing the documentation on msdn I found out about my issue

    TASK_LOGON_S4U

    Use an existing interactive token to run a task. The user must log on using a service for user (S4U) logon. When an S4U logon is used, no password is stored by the system and there is no access to either the network or encrypted files.

    So I changed my task logon type to the Service Account and supplied the NETWORKSERVICE as user id and it resolved my issue. here is the updated code attached

       public Task<int> Launch(string Path, string iniFilePath)
                {
                    try
                    {
                        TaskService taskService = new TaskService();
    
                        const string TaskName = "LaunchTask";
                        if (taskService.FindTask(TaskName) != null)
                        {
                            var task = taskService.FindTask(TaskName);
                        }
    
                    iniFilePath = "\"" + iniFilePath + "\"";
                    string completeArgument = "/portable /skipupdate " + iniFilePath;
                    TaskDefinition taskDefinition = taskService.NewTask();            
                    taskDefinition.Principal.LogonType = TaskLogonType.ServiceAccount;
                    taskDefinition.Principal.UserId = @"NT AUTHORITY\NETWORKSERVICE";
                    taskDefinition.Actions.Add(new ExecAction(mt4Path, completeArgument, null));                          
                    taskDefinition.Settings.Hidden = false;
                    Microsoft.Win32.TaskScheduler.Task mtTask = taskService.RootFolder.RegisterTaskDefinition(TaskName, taskDefinition);
                    RunningTask runningMT4 = mtTask.Run();
                    int processIdMT = (int)runningMT.EnginePID;
                    mt4Task.Folder.DeleteTask(mtTask.Name);
                    return System.Threading.Tasks.Task.FromResult(processIdMT);
                }
                catch
                {
                    throw;
                }
            }
    

    The reason to do this was because I am running this under a Service Fabric project and service fabric was using network service to launch it's tasks.