/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/System.Management.Automation/engine/remoting/client/JobSourceAdapter.cs
545 строк
18 KB
xtqqczze
Fix IDE0083: UseNotPattern (#26213)
17 окт 2025, 21:06
Не верифицирован
17 окт 2025, 21:06
2786fce
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Management.Automation.Runspaces; using System.Runtime.Serialization; // Stops compiler from warning about unknown warnings #pragma warning disable 1634, 1691 namespace System.Management.Automation { /// <summary> /// Contains the definition of a job which is defined in a /// job store. /// </summary> /// <remarks>The actual implementation of this class will /// happen in M2</remarks> public class JobDefinition : ISerializable { private string _name; /// <summary> /// A friendly Name for this definition. /// </summary> public string Name { get { return _name; } set { _name = value; } } /// <summary> /// The type that derives from JobSourceAdapter /// that contains the logic for invocation and /// management of this type of job. /// </summary> public Type JobSourceAdapterType { get; } private string _moduleName; /// <summary> /// Module name for the module containing /// the source adapter implementation. /// </summary> public string ModuleName { get { return _moduleName; } set { _moduleName = value; } } private string _jobSourceAdapterTypeName; /// <summary> /// Job source adapter type name. /// </summary> public string JobSourceAdapterTypeName { get { return _jobSourceAdapterTypeName; } set { _jobSourceAdapterTypeName = value; } } /// <summary> /// Name of the job that needs to be loaded /// from the specified module. /// </summary> public string Command { get; } private Guid _instanceId; /// <summary> /// Unique Guid for this job definition. /// </summary> public Guid InstanceId { get { return _instanceId; } set { _instanceId = value; } } /// <summary> /// Save this definition to the specified /// file on disk. /// </summary> /// <param name="stream">Stream to save to.</param> public virtual void Save(Stream stream) { throw new NotImplementedException(); } /// <summary> /// Load this definition from the specified /// file on disk. /// </summary> /// <param name="stream"></param> public virtual void Load(Stream stream) { throw new NotImplementedException(); } /// <summary> /// Returns information about this job like /// name, definition, parameters etc. /// </summary> public CommandInfo CommandInfo { get { return null; } } /// <summary> /// Public constructor for testing. /// </summary> /// <param name="jobSourceAdapterType">Type of adapter to use to create a job.</param> /// <param name="command">The command string.</param> /// <param name="name">The job name.</param> public JobDefinition(Type jobSourceAdapterType, string command, string name) { JobSourceAdapterType = jobSourceAdapterType; if (jobSourceAdapterType != null) { _jobSourceAdapterTypeName = jobSourceAdapterType.Name; } Command = command; _name = name; _instanceId = Guid.NewGuid(); } /// <summary> /// </summary> /// <param name="info"></param> /// <param name="context"></param> protected JobDefinition(SerializationInfo info, StreamingContext context) { throw new NotImplementedException(); } /// <summary> /// </summary> /// <param name="info"></param> /// <param name="context"></param> public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw new NotImplementedException(); } } /// <summary> /// Class that helps define the parameters to /// be passed to a job so that the job can be /// instantiated without having to specify /// the parameters explicitly. Helps in /// passing job parameters to disk. /// </summary> /// <remarks>This class is not required if /// CommandParameterCollection adds a public /// constructor.The actual implementation of /// this class will happen in M2</remarks> public class JobInvocationInfo : ISerializable { /// <summary> /// Friendly name associated with this specification. /// </summary> public string Name { get { return _name; } set { if (value == null) throw new PSArgumentNullException("value"); _name = value; } } private string _name = string.Empty; private string _command; /// <summary> /// Command string to execute. /// </summary> public string Command { get { return _command ?? _definition.Command; } set { _command = value; } } private JobDefinition _definition; /// <summary> /// Definition associated with the job. /// </summary> public JobDefinition Definition { get { return _definition; } set { _definition = value; } } private List<CommandParameterCollection> _parameters; /// <summary> /// Parameters associated with this specification. /// </summary> public List<CommandParameterCollection> Parameters { get { return _parameters ??= new List<CommandParameterCollection>(); } } /// <summary> /// Unique identifies for this specification. /// </summary> public Guid InstanceId { get; } = Guid.NewGuid(); /// <summary> /// Save this specification to a file. /// </summary> /// <param name="stream">Stream to save to.</param> public virtual void Save(Stream stream) { throw new NotImplementedException(); } /// <summary> /// Load this specification from a file. /// </summary> /// <param name="stream">Stream to load from.</param> public virtual void Load(Stream stream) { throw new NotImplementedException(); } /// <summary> /// Constructor. /// </summary> protected JobInvocationInfo() { } /// <summary> /// Create a new job definition with a single set of parameters. /// </summary> /// <param name="definition">The job definition.</param> /// <param name="parameters">The parameter collection to use.</param> public JobInvocationInfo(JobDefinition definition, Dictionary<string, object> parameters) { _definition = definition; var convertedCollection = ConvertDictionaryToParameterCollection(parameters); if (convertedCollection != null) { Parameters.Add(convertedCollection); } } /// <summary> /// Create a new job definition with a multiple sets of parameters. This allows /// different parameters for different machines. /// </summary> /// <param name="definition">The job definition.</param> /// <param name="parameterCollectionList">Collection of sets of parameters to use for the child jobs.</param> [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is forced by the interaction of PowerShell and Workflow.")] public JobInvocationInfo(JobDefinition definition, IEnumerable<Dictionary<string, object>> parameterCollectionList) { _definition = definition; if (parameterCollectionList == null) return; foreach (var parameterCollection in parameterCollectionList) { if (parameterCollection == null) continue; CommandParameterCollection convertedCollection = ConvertDictionaryToParameterCollection(parameterCollection); if (convertedCollection != null) { Parameters.Add(convertedCollection); } } } /// <summary> /// </summary> /// <param name="definition"></param> /// <param name="parameters"></param> public JobInvocationInfo(JobDefinition definition, CommandParameterCollection parameters) { _definition = definition; Parameters.Add(parameters ?? new CommandParameterCollection()); } /// <summary> /// </summary> /// <param name="definition"></param> /// <param name="parameters"></param> public JobInvocationInfo(JobDefinition definition, IEnumerable<CommandParameterCollection> parameters) { _definition = definition; if (parameters == null) return; foreach (var parameter in parameters) { Parameters.Add(parameter); } } /// <summary> /// </summary> /// <param name="info"></param> /// <param name="context"></param> protected JobInvocationInfo(SerializationInfo info, StreamingContext context) { throw new NotImplementedException(); } /// <summary> /// </summary> /// <param name="info"></param> /// <param name="context"></param> public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw new NotImplementedException(); } /// <summary> /// Utility function to turn a dictionary of name/value pairs into a parameter collection. /// </summary> /// <param name="parameters">The dictionary to convert.</param> /// <returns>The converted collection.</returns> private static CommandParameterCollection ConvertDictionaryToParameterCollection(IEnumerable<KeyValuePair<string, object>> parameters) { if (parameters == null) return null; CommandParameterCollection paramCollection = new CommandParameterCollection(); foreach (CommandParameter paramItem in parameters.Select(static param => new CommandParameter(param.Key, param.Value))) { paramCollection.Add(paramItem); } return paramCollection; } } /// <summary> /// Abstract class for a job store which will /// contain the jobs of a specific type. /// </summary> public abstract class JobSourceAdapter { /// <summary> /// Name for this store. /// </summary> public string Name { get; set; } = string.Empty; /// <summary> /// Get a token that allows for construction of a job with a previously assigned /// Id and InstanceId. This is only possible if this JobSourceAdapter is the /// creator of the original job. /// The original job must have been saved using "SaveJobIdForReconstruction" /// </summary> /// <param name="instanceId">Instance Id of the job to recreate.</param> /// <returns>JobIdentifier to be used in job construction.</returns> protected JobIdentifier RetrieveJobIdForReuse(Guid instanceId) { return JobManager.GetJobIdentifier(instanceId, this.GetType().Name); } /// <summary> /// Saves the Id information for a job so that it can be constructed at a later time. /// This will only allow this job source adapter type to recreate the job. /// </summary> /// <param name="job">The job whose id information to store.</param> /// <param name="recurse">Recurse to save child job Ids.</param> [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Only jobs that derive from Job2 should have reusable IDs.")] public void StoreJobIdForReuse(Job2 job, bool recurse) { if (job == null) { PSTraceSource.NewArgumentNullException(nameof(job), RemotingErrorIdStrings.JobSourceAdapterCannotSaveNullJob); } JobManager.SaveJobId(job.InstanceId, job.Id, this.GetType().Name); if (recurse && job.ChildJobs != null && job.ChildJobs.Count > 0) { Hashtable duplicateDetector = new Hashtable(); duplicateDetector.Add(job.InstanceId, job.InstanceId); foreach (Job child in job.ChildJobs) { if (child is not Job2 childJob) continue; StoreJobIdForReuseHelper(duplicateDetector, childJob, true); } } } private void StoreJobIdForReuseHelper(Hashtable duplicateDetector, Job2 job, bool recurse) { if (duplicateDetector.ContainsKey(job.InstanceId)) return; duplicateDetector.Add(job.InstanceId, job.InstanceId); JobManager.SaveJobId(job.InstanceId, job.Id, this.GetType().Name); if (!recurse || job.ChildJobs == null) return; foreach (Job child in job.ChildJobs) { if (child is not Job2 childJob) continue; StoreJobIdForReuseHelper(duplicateDetector, childJob, recurse); } } /// <summary> /// Create a new job with the specified definition. /// </summary> /// <param name="definition">Job definition to use.</param> /// <returns>Job object.</returns> public Job2 NewJob(JobDefinition definition) { return NewJob(new JobInvocationInfo(definition, new Dictionary<string, object>())); } /// <summary> /// Creates a new job with the definition as specified by /// the provided definition name and path. If path is null /// then a default location will be used to find the job /// definition by name. /// </summary> /// <param name="definitionName">Job definition name.</param> /// <param name="definitionPath">Job definition file path.</param> /// <returns>Job2 object.</returns> public virtual Job2 NewJob(string definitionName, string definitionPath) { return null; } /// <summary> /// Create a new job with the specified JobSpecification. /// </summary> /// <param name="specification">Specification.</param> /// <returns>Job object.</returns> public abstract Job2 NewJob(JobInvocationInfo specification); /// <summary> /// Get the list of jobs that are currently available in this /// store. /// </summary> /// <returns>Collection of job objects.</returns> public abstract IList<Job2> GetJobs(); /// <summary> /// Get list of jobs that matches the specified names. /// </summary> /// <param name="name">names to match, can support /// wildcard if the store supports</param> /// <param name="recurse"></param> /// <returns>Collection of jobs that match the specified /// criteria.</returns> public abstract IList<Job2> GetJobsByName(string name, bool recurse); /// <summary> /// Get list of jobs that run the specified command. /// </summary> /// <param name="command">Command to match.</param> /// <param name="recurse"></param> /// <returns>Collection of jobs that match the specified /// criteria.</returns> public abstract IList<Job2> GetJobsByCommand(string command, bool recurse); /// <summary> /// Get list of jobs that has the specified id. /// </summary> /// <param name="instanceId">Guid to match.</param> /// <param name="recurse"></param> /// <returns>Job with the specified guid.</returns> public abstract Job2 GetJobByInstanceId(Guid instanceId, bool recurse); /// <summary> /// Get job that has specific session id. /// </summary> /// <param name="id">Id to match.</param> /// <param name="recurse"></param> /// <returns>Job with the specified id.</returns> public abstract Job2 GetJobBySessionId(int id, bool recurse); /// <summary> /// Get list of jobs that are in the specified state. /// </summary> /// <param name="state">State to match.</param> /// <param name="recurse"></param> /// <returns>Collection of jobs with the specified /// state.</returns> public abstract IList<Job2> GetJobsByState(JobState state, bool recurse); /// <summary> /// Get list of jobs based on the adapter specific /// filter parameters. /// </summary> /// <param name="filter">dictionary containing name value /// pairs for adapter specific filters</param> /// <param name="recurse"></param> /// <returns>Collection of jobs that match the /// specified criteria.</returns> public abstract IList<Job2> GetJobsByFilter(Dictionary<string, object> filter, bool recurse); /// <summary> /// Remove a job from the store. /// </summary> /// <param name="job">Job object to remove.</param> public abstract void RemoveJob(Job2 job); /// <summary> /// Saves the job to a persisted store. /// </summary> /// <param name="job">Job2 type job to persist.</param> public virtual void PersistJob(Job2 job) { // Implemented only if job needs to be told when to persist. } } }