684 lines
26 KiB
C#
684 lines
26 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Management.Automation;
|
|
using System.Security.AccessControl;
|
|
using System.Security.Principal;
|
|
using System.Text;
|
|
|
|
namespace Microsoft.PowerShell.ScheduledJob
|
|
{
|
|
/// <summary>
|
|
/// This class encapsulates the work of determining the file location where
|
|
/// a job definition will be stored and retrieved and where job runs will
|
|
/// be stored and retrieved. Scheduled job definitions are stored in a
|
|
/// location based on the current user. Job runs are stored in the
|
|
/// corresponding scheduled job definition location under an "Output"
|
|
/// directory, where each run will have a subdirectory with a name derived
|
|
/// from the job run date/time.
|
|
///
|
|
/// File Structure for "JobDefinitionFoo":
|
|
/// $env:User\AppData\Local\Windows\PowerShell\ScheduledJobs\JobDefinitionFoo\
|
|
/// ScheduledJobDefinition.xml
|
|
/// Output\
|
|
/// 110321-130942\
|
|
/// Status.xml
|
|
/// Results.xml
|
|
/// 110319-173502\
|
|
/// Status.xml
|
|
/// Results.xml
|
|
/// ...
|
|
/// </summary>
|
|
internal class ScheduledJobStore
|
|
{
|
|
#region Public Enums
|
|
|
|
public enum JobRunItem
|
|
{
|
|
None = 0,
|
|
Status = 1,
|
|
Results = 2
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Strings
|
|
|
|
public const string ScheduledJobsPath = @"Microsoft\Windows\PowerShell\ScheduledJobs";
|
|
public const string DefinitionFileName = "ScheduledJobDefinition";
|
|
public const string JobRunOutput = "Output";
|
|
public const string ScheduledJobDefExistsFQEID = "ScheduledJobDefExists";
|
|
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Returns FileStream object for existing scheduled job definition.
|
|
/// Definition file is looked for in the default user local appdata path.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled job definition name.</param>
|
|
/// <param name="fileMode">File mode.</param>
|
|
/// <param name="fileAccess">File access.</param>
|
|
/// <param name="fileShare">File share.</param>
|
|
/// <returns>FileStream object.</returns>
|
|
public static FileStream GetFileForJobDefinition(
|
|
string definitionName,
|
|
FileMode fileMode,
|
|
FileAccess fileAccess,
|
|
FileShare fileShare)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
string filePathName = GetFilePathName(definitionName, DefinitionFileName);
|
|
return File.Open(filePathName, fileMode, fileAccess, fileShare);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns FileStream object for existing scheduled job definition.
|
|
/// Definition file is looked for in the path provided.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled job definition name.</param>
|
|
/// <param name="definitionPath">Scheduled job definition file path.</param>
|
|
/// <param name="fileMode">File mode.</param>
|
|
/// <param name="fileAccess">File share.</param>
|
|
/// <param name="fileShare">File share.</param>
|
|
/// <returns></returns>
|
|
public static FileStream GetFileForJobDefinition(
|
|
string definitionName,
|
|
string definitionPath,
|
|
FileMode fileMode,
|
|
FileAccess fileAccess,
|
|
FileShare fileShare)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(definitionPath))
|
|
{
|
|
throw new PSArgumentException("definitionPath");
|
|
}
|
|
|
|
string filePathName = string.Format(CultureInfo.InvariantCulture, @"{0}\{1}\{2}.xml",
|
|
definitionPath, definitionName, DefinitionFileName);
|
|
return File.Open(filePathName, fileMode, fileAccess, fileShare);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks the provided path against the the default path of scheduled jobs
|
|
/// for the current user.
|
|
/// </summary>
|
|
/// <param name="definitionPath">Path for scheduled job definitions.</param>
|
|
/// <returns>True if paths are equal.</returns>
|
|
public static bool IsDefaultUserPath(string definitionPath)
|
|
{
|
|
return definitionPath.Equals(GetJobDefinitionLocation(), StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a FileStream object for a new scheduled job definition name.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled job definition name.</param>
|
|
/// <returns>FileStream object.</returns>
|
|
public static FileStream CreateFileForJobDefinition(
|
|
string definitionName)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
string filePathName = CreateFilePathName(definitionName, DefinitionFileName);
|
|
return File.Create(filePathName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an IEnumerable object of scheduled job definition names in
|
|
/// the job store.
|
|
/// </summary>
|
|
/// <returns>IEnumerable of job definition names.</returns>
|
|
public static IEnumerable<string> GetJobDefinitions()
|
|
{
|
|
// Directory names are identical to the corresponding scheduled job definition names.
|
|
string directoryPath = GetDirectoryPath();
|
|
IEnumerable<string> definitions = Directory.EnumerateDirectories(directoryPath);
|
|
return (definitions != null) ? definitions : new Collection<string>() as IEnumerable<string>;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a FileStream object for an existing scheduled job definition
|
|
/// run.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled job definition name.</param>
|
|
/// <param name="runStart">DateTime of job run start time.</param>
|
|
/// <param name="runItem">Job run item.</param>
|
|
/// <param name="fileAccess">File access.</param>
|
|
/// <param name="fileMode">File mode.</param>
|
|
/// <param name="fileShare">File share.</param>
|
|
/// <returns>FileStream object.</returns>
|
|
public static FileStream GetFileForJobRunItem(
|
|
string definitionName,
|
|
DateTime runStart,
|
|
JobRunItem runItem,
|
|
FileMode fileMode,
|
|
FileAccess fileAccess,
|
|
FileShare fileShare)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
string filePathName = GetRunFilePathName(definitionName, runItem, runStart);
|
|
return File.Open(filePathName, fileMode, fileAccess, fileShare);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a FileStream object for a new scheduled job definition run.
|
|
/// </summary>
|
|
/// <param name="definitionOutputPath">Scheduled job definition path.</param>
|
|
/// <param name="runStart">DateTime of job run start time.</param>
|
|
/// <param name="runItem">Job run item.</param>
|
|
/// <returns>FileStream object.</returns>
|
|
public static FileStream CreateFileForJobRunItem(
|
|
string definitionOutputPath,
|
|
DateTime runStart,
|
|
JobRunItem runItem)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionOutputPath))
|
|
{
|
|
throw new PSArgumentException("definitionOutputPath");
|
|
}
|
|
|
|
string filePathName = GetRunFilePathNameFromPath(definitionOutputPath, runItem, runStart);
|
|
|
|
// If the file already exists, we overwrite it because the job run
|
|
// can be updated multiple times while the job is running.
|
|
return File.Create(filePathName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a collection of DateTime objects which specify job run directories
|
|
/// that are currently in the store.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled job definition name.</param>
|
|
/// <returns>Collection of DateTime objects.</returns>
|
|
public static Collection<DateTime> GetJobRunsForDefinition(
|
|
string definitionName)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
string definitionOutputPath = GetJobRunOutputDirectory(definitionName);
|
|
|
|
return GetJobRunsForDefinitionPath(definitionOutputPath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a collection of DateTime objects which specify job run directories
|
|
/// that are currently in the store.
|
|
/// </summary>
|
|
/// <param name="definitionOutputPath">Scheduled job definition job run Output path.</param>
|
|
/// <returns>Collection of DateTime objects.</returns>
|
|
public static Collection<DateTime> GetJobRunsForDefinitionPath(
|
|
string definitionOutputPath)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionOutputPath))
|
|
{
|
|
throw new PSArgumentException("definitionOutputPath");
|
|
}
|
|
|
|
Collection<DateTime> jobRunInfos = new Collection<DateTime>();
|
|
IEnumerable<string> jobRuns = Directory.EnumerateDirectories(definitionOutputPath);
|
|
if (jobRuns != null)
|
|
{
|
|
// Job run directory names are the date/times that the job was started.
|
|
foreach (string jobRun in jobRuns)
|
|
{
|
|
DateTime jobRunDateTime;
|
|
int indx = jobRun.LastIndexOf('\\');
|
|
string jobRunName = (indx != -1) ? jobRun.Substring(indx + 1) : jobRun;
|
|
if (ConvertJobRunNameToDateTime(jobRunName, out jobRunDateTime))
|
|
{
|
|
jobRunInfos.Add(jobRunDateTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
return jobRunInfos;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove the job definition and all job runs from job store.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled Job Definition name.</param>
|
|
public static void RemoveJobDefinition(
|
|
string definitionName)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
// Remove job runs, job definition file, and job definition directory.
|
|
string jobDefDirectory = GetJobDefinitionPath(definitionName);
|
|
Directory.Delete(jobDefDirectory, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Renames the directory containing the old job definition name
|
|
/// to the new name provided.
|
|
/// </summary>
|
|
/// <param name="oldDefName">Existing job definition directory.</param>
|
|
/// <param name="newDefName">Renamed job definition directory.</param>
|
|
public static void RenameScheduledJobDefDir(
|
|
string oldDefName,
|
|
string newDefName)
|
|
{
|
|
if (string.IsNullOrEmpty(oldDefName))
|
|
{
|
|
throw new PSArgumentException("oldDefName");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(newDefName))
|
|
{
|
|
throw new PSArgumentException("newDefName");
|
|
}
|
|
|
|
string oldDirPath = GetJobDefinitionPath(oldDefName);
|
|
string newDirPath = GetJobDefinitionPath(newDefName);
|
|
Directory.Move(oldDirPath, newDirPath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a single job definition job run from the job store.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled Job Definition name.</param>
|
|
/// <param name="runStart">DateTime of job run.</param>
|
|
public static void RemoveJobRun(
|
|
string definitionName,
|
|
DateTime runStart)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
// Remove the job run files and directory.
|
|
string runDirectory = GetRunDirectory(definitionName, runStart);
|
|
Directory.Delete(runDirectory, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a single job definition job run from the job store.
|
|
/// </summary>
|
|
/// <param name="definitionOutputPath">Scheduled Job Definition Output path.</param>
|
|
/// <param name="runStart">DateTime of job run.</param>
|
|
public static void RemoveJobRunFromOutputPath(
|
|
string definitionOutputPath,
|
|
DateTime runStart)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionOutputPath))
|
|
{
|
|
throw new PSArgumentException("definitionOutputPath");
|
|
}
|
|
|
|
// Remove the job run files and directory.
|
|
string runDirectory = GetRunDirectoryFromPath(definitionOutputPath, runStart);
|
|
Directory.Delete(runDirectory, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove all job runs for this job definition.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled Job Definition name.</param>
|
|
public static void RemoveAllJobRuns(
|
|
string definitionName)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
Collection<DateTime> jobRuns = GetJobRunsForDefinition(definitionName);
|
|
foreach (DateTime jobRun in jobRuns)
|
|
{
|
|
string jobRunPath = GetRunDirectory(definitionName, jobRun);
|
|
Directory.Delete(jobRunPath, true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set read access on provided definition file for specified user.
|
|
/// </summary>
|
|
/// <param name="definitionName">Definition name.</param>
|
|
/// <param name="user">Account user name.</param>
|
|
public static void SetReadAccessOnDefinitionFile(
|
|
string definitionName,
|
|
string user)
|
|
{
|
|
string filePath = GetFilePathName(definitionName, DefinitionFileName);
|
|
|
|
// Get file security for existing file.
|
|
FileSecurity fileSecurity = new FileSecurity(
|
|
filePath,
|
|
AccessControlSections.Access);
|
|
|
|
// Create rule.
|
|
FileSystemAccessRule fileAccessRule = new FileSystemAccessRule(
|
|
user,
|
|
FileSystemRights.Read,
|
|
AccessControlType.Allow);
|
|
fileSecurity.AddAccessRule(fileAccessRule);
|
|
|
|
// Apply rule.
|
|
File.SetAccessControl(filePath, fileSecurity);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set write access on Output directory for provided definition for
|
|
/// specified user.
|
|
/// </summary>
|
|
/// <param name="definitionName">Definition name.</param>
|
|
/// <param name="user">Account user name.</param>
|
|
public static void SetWriteAccessOnJobRunOutput(
|
|
string definitionName,
|
|
string user)
|
|
{
|
|
string outputDirectoryPath = GetJobRunOutputDirectory(definitionName);
|
|
AddFullAccessToDirectory(user, outputDirectoryPath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the directory path for job run output for the specified
|
|
/// scheduled job definition.
|
|
/// </summary>
|
|
/// <param name="definitionName">Definition name.</param>
|
|
/// <returns>Directory Path.</returns>
|
|
public static string GetJobRunOutputDirectory(
|
|
string definitionName)
|
|
{
|
|
if (string.IsNullOrEmpty(definitionName))
|
|
{
|
|
throw new PSArgumentException("definitionName");
|
|
}
|
|
|
|
return Path.Combine(GetJobDefinitionPath(definitionName), JobRunOutput);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the directory path for a Scheduled Job Definition.
|
|
/// </summary>
|
|
/// <returns>Directory Path.</returns>
|
|
public static string GetJobDefinitionLocation()
|
|
{
|
|
#if UNIX
|
|
return Path.Combine(Platform.SelectProductNameForDirectory(Platform.XDG_Type.CACHE), "ScheduledJobs"));
|
|
#else
|
|
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ScheduledJobsPath);
|
|
#endif
|
|
}
|
|
|
|
public static void CreateDirectoryIfNotExists()
|
|
{
|
|
GetDirectoryPath();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Gets the directory path for Scheduled Jobs. Will create the directory if
|
|
/// it does not exist.
|
|
/// </summary>
|
|
/// <returns>Directory Path.</returns>
|
|
private static string GetDirectoryPath()
|
|
{
|
|
string pathName;
|
|
#if UNIX
|
|
pathName = Path.Combine(Platform.SelectProductNameForDirectory(Platform.XDG_Type.CACHE), "ScheduledJobs"));
|
|
#else
|
|
pathName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ScheduledJobsPath);
|
|
#endif
|
|
if (!Directory.Exists(pathName))
|
|
{
|
|
Directory.CreateDirectory(pathName);
|
|
}
|
|
|
|
return pathName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a ScheduledJob definition directory with provided definition name
|
|
/// along with a job run Output directory, and returns a file path/name.
|
|
/// ...\ScheduledJobs\definitionName\fileName.xml
|
|
/// ...\ScheduledJobs\definitionName\Output\
|
|
/// </summary>
|
|
/// <param name="definitionName">Definition name.</param>
|
|
/// <param name="fileName">File name.</param>
|
|
/// <returns>File path/name.</returns>
|
|
private static string CreateFilePathName(string definitionName, string fileName)
|
|
{
|
|
string filePath = GetJobDefinitionPath(definitionName);
|
|
string outputPath = GetJobRunOutputDirectory(definitionName);
|
|
if (Directory.Exists(filePath))
|
|
{
|
|
ScheduledJobException ex = new ScheduledJobException(StringUtil.Format(ScheduledJobErrorStrings.JobDefFileAlreadyExists, definitionName));
|
|
ex.FQEID = ScheduledJobDefExistsFQEID;
|
|
throw ex;
|
|
}
|
|
|
|
Directory.CreateDirectory(filePath);
|
|
Directory.CreateDirectory(outputPath);
|
|
return string.Format(CultureInfo.InstalledUICulture, @"{0}\{1}.xml", filePath, fileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a file path/name for an existing Scheduled job definition directory.
|
|
/// </summary>
|
|
/// <param name="definitionName">Definition name.</param>
|
|
/// <param name="fileName">File name.</param>
|
|
/// <returns>File path/name.</returns>
|
|
private static string GetFilePathName(string definitionName, string fileName)
|
|
{
|
|
string filePath = GetJobDefinitionPath(definitionName);
|
|
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}.xml", filePath, fileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the directory path for a Scheduled Job Definition.
|
|
/// </summary>
|
|
/// <param name="definitionName">Scheduled job definition name.</param>
|
|
/// <returns>Directory Path.</returns>
|
|
private static string GetJobDefinitionPath(string definitionName)
|
|
{
|
|
#if UNIX
|
|
return Path.Combine(Platform.SelectProductNameForDirectory(Platform.XDG_Type.CACHE), "ScheduledJobs", definitionName);
|
|
#else
|
|
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
|
ScheduledJobsPath,
|
|
definitionName);
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a directory path for an existing ScheduledJob run result directory.
|
|
/// </summary>
|
|
/// <param name="definitionName">Definition name.</param>
|
|
/// <param name="runStart">File name.</param>
|
|
/// <returns>Directory Path.</returns>
|
|
private static string GetRunDirectory(
|
|
string definitionName,
|
|
DateTime runStart)
|
|
{
|
|
string directoryPath = GetJobRunOutputDirectory(definitionName);
|
|
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", directoryPath,
|
|
ConvertDateTimeToJobRunName(runStart));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a directory path for an existing ScheduledJob run based on
|
|
/// provided definition Output directory path.
|
|
/// </summary>
|
|
/// <param name="definitionOutputPath">Output directory path.</param>
|
|
/// <param name="runStart">File name.</param>
|
|
/// <returns>Directory Path.</returns>
|
|
private static string GetRunDirectoryFromPath(
|
|
string definitionOutputPath,
|
|
DateTime runStart)
|
|
{
|
|
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}",
|
|
definitionOutputPath, ConvertDateTimeToJobRunName(runStart));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a file path/name for a run result file. Will create the
|
|
/// job run directory if it does not exist.
|
|
/// </summary>
|
|
/// <param name="definitionName">Definition name.</param>
|
|
/// <param name="runItem">Result type.</param>
|
|
/// <param name="runStart">Run date.</param>
|
|
/// <returns>File path/name.</returns>
|
|
private static string GetRunFilePathName(
|
|
string definitionName,
|
|
JobRunItem runItem,
|
|
DateTime runStart)
|
|
{
|
|
string directoryPath = GetJobRunOutputDirectory(definitionName);
|
|
string jobRunPath = string.Format(CultureInfo.InvariantCulture, @"{0}\{1}",
|
|
directoryPath, ConvertDateTimeToJobRunName(runStart));
|
|
|
|
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}.xml", jobRunPath,
|
|
runItem.ToString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a file path/name for a job run result, based on the passed in
|
|
/// job run output path. Will create the job run directory if it does not
|
|
/// exist.
|
|
/// </summary>
|
|
/// <param name="outputPath">Definition job run output path.</param>
|
|
/// <param name="runItem">Result type.</param>
|
|
/// <param name="runStart">Run date.</param>
|
|
/// <returns></returns>
|
|
private static string GetRunFilePathNameFromPath(
|
|
string outputPath,
|
|
JobRunItem runItem,
|
|
DateTime runStart)
|
|
{
|
|
string jobRunPath = string.Format(CultureInfo.InvariantCulture, @"{0}\{1}",
|
|
outputPath, ConvertDateTimeToJobRunName(runStart));
|
|
|
|
if (!Directory.Exists(jobRunPath))
|
|
{
|
|
// Create directory for this job run date.
|
|
Directory.CreateDirectory(jobRunPath);
|
|
}
|
|
|
|
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}.xml", jobRunPath,
|
|
runItem.ToString());
|
|
}
|
|
|
|
private static void AddFullAccessToDirectory(
|
|
string user,
|
|
string directoryPath)
|
|
{
|
|
// Create rule.
|
|
DirectoryInfo info = new DirectoryInfo(directoryPath);
|
|
DirectorySecurity dSecurity = info.GetAccessControl();
|
|
FileSystemAccessRule fileAccessRule = new FileSystemAccessRule(
|
|
user,
|
|
FileSystemRights.FullControl,
|
|
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
|
|
PropagationFlags.None,
|
|
AccessControlType.Allow);
|
|
|
|
// Apply rule.
|
|
dSecurity.AddAccessRule(fileAccessRule);
|
|
info.SetAccessControl(dSecurity);
|
|
}
|
|
|
|
//
|
|
// String format: 'YYYYMMDD-HHMMSS-SSS'
|
|
// ,where SSS is milliseconds.
|
|
//
|
|
|
|
private static string ConvertDateTimeToJobRunName(DateTime dt)
|
|
{
|
|
return string.Format(CultureInfo.InvariantCulture,
|
|
@"{0:d4}{1:d2}{2:d2}-{3:d2}{4:d2}{5:d2}-{6:d3}",
|
|
dt.Year, dt.Month, dt.Day,
|
|
dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a jobRun name string to an equivalent DateTime.
|
|
/// </summary>
|
|
/// <param name="jobRunName"></param>
|
|
/// <param name="jobRun"></param>
|
|
/// <returns></returns>
|
|
internal static bool ConvertJobRunNameToDateTime(string jobRunName, out DateTime jobRun)
|
|
{
|
|
if (jobRunName == null || jobRunName.Length != 19)
|
|
{
|
|
jobRun = new DateTime();
|
|
return false;
|
|
}
|
|
|
|
int year = 0;
|
|
int month = 0;
|
|
int day = 0;
|
|
int hour = 0;
|
|
int minute = 0;
|
|
int second = 0;
|
|
int msecs = 0;
|
|
bool success = true;
|
|
|
|
try
|
|
{
|
|
year = Convert.ToInt32(jobRunName.Substring(0, 4));
|
|
month = Convert.ToInt32(jobRunName.Substring(4, 2));
|
|
day = Convert.ToInt32(jobRunName.Substring(6, 2));
|
|
hour = Convert.ToInt32(jobRunName.Substring(9, 2));
|
|
minute = Convert.ToInt32(jobRunName.Substring(11, 2));
|
|
second = Convert.ToInt32(jobRunName.Substring(13, 2));
|
|
msecs = Convert.ToInt32(jobRunName.Substring(16, 3));
|
|
}
|
|
catch (FormatException)
|
|
{
|
|
success = false;
|
|
}
|
|
catch (OverflowException)
|
|
{
|
|
success = false;
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
jobRun = new DateTime(year, month, day, hour, minute, second, msecs);
|
|
}
|
|
else
|
|
{
|
|
jobRun = new DateTime();
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|