ExecAction.Path property isn't stripping off quotes when retrieved

Aug 4, 2016 at 3:03 AM
If you have a scheduled task and the task's program/script path has quotations in it, the library isn't returning a proper path using the Path() property (ie. it's keeping the quotations).
Dim execActionPath As String
If taskObject.Definition.Actions.Count = 1 Then
  execActionPath = DirectCast(taskObject.Definition.Actions(0), TaskScheduler.ExecAction).Path
End If
As a workaround to this issue I added this to my code...
If execActionPath.Contains(Chr(34)) = True Then
  execActionPath = execActionPath.Replace(Chr(34), "")
End If
Aug 4, 2016 at 8:01 PM
I have done some more testing. I set up two test tasks, one with an action with a path to an executable with no spaces in the path and another with spaces in the path. The TaskScheduler library returned a proper path (that is, one without quotes) for the first task but an incorrect path (that is, one with quotes) for the second task.

Aug 4, 2016 at 8:01 PM
Edited Aug 4, 2016 at 8:03 PM
I have confirmed that it will consistently return exactly what was put in. If the property was initially set with a quoted path, a quoted path will be returned. This is not a bug, but how the base Windows library works with the input strings.
Marked as answer by dahall on 8/4/2016 at 4:37 PM
Aug 4, 2016 at 8:04 PM
The way it appears is that the Windows Task Scheduler only includes quotes in the path when the path has spaces in it. Unfortunately the TaskScheduler library doesn't take this into account hence my hack-ish workaround.
Aug 4, 2016 at 8:10 PM
Edited Aug 4, 2016 at 8:11 PM
With the way that the TaskScheduler library handles paths, I would need to implement that code hack whenever my program goes to verify if the task action paths are valid.

My code path works like this...
Check if the task exists which uses a call to the doesTaskExist() function. That function first checks to see if the actual task exists. It then checks the ExecAction path and makes sure that the associated ExecAction path exists or not. This is where things can break down. If the library returns a path with quotes in it and I just feed it to a call of IO.File.Exists() then the program will think that the executable doesn't exist thus making the task invalid.
Aug 4, 2016 at 9:24 PM
Edited Aug 4, 2016 at 9:25 PM
In other words, before taking the path from the library and feeding it into IO.File.Exists() I will have to strip off any and all quotes before calling it or IO.File.Exists() will return an incorrect response.

Great... gots to love Windows sometimes. There are times it just makes no damn sense.
Aug 4, 2016 at 11:49 PM
While the base library from Microsoft doesn't do any checking for the Path value, it appears their Management Console applet does validate the path and normalizes it as you indicated (i.e. quotes if spaces included, otherwise no quotes). I'm hesitant to force validation in this wrapper that differs from the behavior of the base library. However, I will make sure the UI library does that validation.
Aug 4, 2016 at 11:55 PM
Edited Aug 5, 2016 at 1:41 AM
You can make it an optional ability of the Path property. You can include a way to pass a Boolean value if you want it normalized. By default it returns a non-normalized value but if you pass a True value to the Path property it returns a normalized path.
Aug 5, 2016 at 1:48 PM
As a property, it can't take parameters. From a library standpoint, given that the native property will return whatever was put in, my inclination is to validate the input using a separate method like 'SetValidatedPath(string filePath)'. Then, the correct value would always be set and therefore always correct on return. What do you think?
Aug 5, 2016 at 5:39 PM
You mean... GetValidatedPath().
Aug 5, 2016 at 6:08 PM
You could put a new property into the ExecAction class.

Add this at the top of the Class right below the ScriptIdentifer variable.
        /// <summary>
        /// Tells the Path property if it should return a fully validated executable path. The default setting is False.
        /// </summary>
        public bool validatePath = false;
And then finally put this in...
                if (this.validatePath)
                    return GetProperty<string, IExecAction>(nameof(Path), "");
                    return GetProperty<string, IExecAction>(nameof(Path), "").Replace("\"", "");
Aug 5, 2016 at 8:19 PM
SetValidatedPath is what I intended. If correct on input, then it will be correct on retrieval. It is more important to make sure it is correct on input so that the action will actually do something. Doing it this way will also maintain the integrity of the expected behaviors.
Aug 6, 2016 at 1:58 AM
Edited Aug 6, 2016 at 1:59 AM
Then basically you're telling me that I'm just going to have to include my own code to sanitize the output of the Path property when retrieving the path of the ExecAction. I need to do this since every run time of the program has a function that checks to see if the task's ExecAction path is valid in the sense that the file exists which involves sending the path property through IO.File.Exists() function. Without a sanitized path, that is, one without quotes, the IO.File.Exists() function returns an incorrect returned value.

I was hoping that you would include it since you have far more knowledge of how a path passed from the Windows Task Scheduler than I do and how it could get mangled in the process.

Yes, I understand that when creating your task you should take care when setting things up for your task but what if someone decides to mangle the task that your program depends upon? They could change the path of the ExecAction thus making your task invalid. The purpose of the code that I have in my program is to make sure that that doesn't happen and if it does detect that the task has been mangled by the user, it deletes the task and re-creates it.