2020-03-24 19:08:37 +01:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
2018-02-13 18:23:53 +01:00
|
|
|
// Licensed under the MIT License.
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
#region Using directives
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Globalization;
|
|
|
|
using System.Management.Automation;
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading;
|
|
|
|
using Microsoft.Management.Infrastructure.Generic;
|
|
|
|
using Microsoft.Management.Infrastructure.Options;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
namespace Microsoft.Management.Infrastructure.CimCmdlets
|
|
|
|
{
|
|
|
|
#region Context base class
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Context base class for cross operations
|
2016-07-14 04:27:37 +02:00
|
|
|
/// for example, some cmdlets need to query instance first and then
|
|
|
|
/// remove instance, those scenarios need context object transferred
|
2016-08-26 22:46:03 +02:00
|
|
|
/// from one operation to another.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
internal abstract class XOperationContextBase
|
|
|
|
{
|
|
|
|
/// <summary>
|
2016-08-26 22:46:03 +02:00
|
|
|
/// <para>namespace</para>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
internal string Namespace
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.nameSpace;
|
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
protected string nameSpace;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
2020-04-14 23:34:53 +02:00
|
|
|
/// Session proxy.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
internal CimSessionProxy Proxy
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.proxy;
|
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
protected CimSessionProxy proxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Class provides all information regarding the
|
2020-04-14 23:34:53 +02:00
|
|
|
/// current invocation to the .NET API.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
internal class InvocationContext
|
|
|
|
{
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="InvocationContext"/> class.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="proxy"></param>
|
|
|
|
internal InvocationContext(CimSessionProxy proxy)
|
|
|
|
{
|
|
|
|
if (proxy != null)
|
|
|
|
{
|
|
|
|
this.ComputerName = proxy.CimSession.ComputerName;
|
|
|
|
this.TargetCimInstance = proxy.TargetCimInstance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="InvocationContext"/> class.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="proxy"></param>
|
|
|
|
internal InvocationContext(string computerName, CimInstance targetCimInstance)
|
|
|
|
{
|
|
|
|
this.ComputerName = computerName;
|
|
|
|
this.TargetCimInstance = targetCimInstance;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// ComputerName of the session
|
|
|
|
/// </para>
|
2020-11-26 06:36:23 +01:00
|
|
|
/// </summary>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <remarks>
|
|
|
|
/// return value could be null
|
|
|
|
/// </remarks>
|
2020-09-02 05:11:16 +02:00
|
|
|
internal virtual string ComputerName { get; }
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// CimInstance on which the current operation against.
|
|
|
|
/// </para>
|
2020-11-26 06:36:23 +01:00
|
|
|
/// </summary>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <remarks>
|
|
|
|
/// return value could be null
|
|
|
|
/// </remarks>
|
2020-09-02 05:11:16 +02:00
|
|
|
internal virtual CimInstance TargetCimInstance { get; }
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
2016-08-26 22:46:03 +02:00
|
|
|
#region Preprocessing of result object interface
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Defines a method to preprocessing an result object before sending to
|
|
|
|
/// output pipeline.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
[ComVisible(false)]
|
|
|
|
internal interface IObjectPreProcess
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Performs pre processing of given result object.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="resultObject"></param>
|
2018-12-25 17:43:03 +01:00
|
|
|
/// <returns>Pre-processed object.</returns>
|
2016-07-14 04:27:37 +02:00
|
|
|
object Process(object resultObject);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Eventargs class
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// CmdletActionEventArgs holds a CimBaseAction object
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
internal sealed class CmdletActionEventArgs : EventArgs
|
|
|
|
{
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CmdletActionEventArgs"/> class.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="action">CimBaseAction object bound to the event.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
public CmdletActionEventArgs(CimBaseAction action)
|
|
|
|
{
|
|
|
|
this.Action = action;
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
public readonly CimBaseAction Action;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// OperationEventArgs holds a cancellation object, and an operation.
|
|
|
|
/// </summary>
|
|
|
|
internal sealed class OperationEventArgs : EventArgs
|
|
|
|
{
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="OperationEventArgs"/> class.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="operationCancellation">Object used to cancel the operation.</param>
|
|
|
|
/// <param name="operation">Async observable operation.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
public OperationEventArgs(IDisposable operationCancellation,
|
|
|
|
IObservable<object> operation,
|
|
|
|
bool theSuccess)
|
|
|
|
{
|
|
|
|
this.operationCancellation = operationCancellation;
|
|
|
|
this.operation = operation;
|
|
|
|
this.success = theSuccess;
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
public readonly IDisposable operationCancellation;
|
|
|
|
public readonly IObservable<object> operation;
|
|
|
|
public readonly bool success;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Wrapper of <see cref="CimSession"/> object.
|
|
|
|
/// A CimSessionProxy object can only execute one operation at specific moment.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
internal class CimSessionProxy : IDisposable
|
|
|
|
{
|
|
|
|
#region static members
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// global operation counter
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
private static long gOperationCounter = 0;
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Temporary CimSession cache lock.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-21 15:29:44 +01:00
|
|
|
private static readonly object temporarySessionCacheLock = new();
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>temporary CimSession cache</para>
|
|
|
|
/// <para>Temporary CimSession means the session is created by cimcmdlets,
|
|
|
|
/// which is not created by <see cref="New-CimSession"/> cmdlet.
|
|
|
|
/// Due to some cmdlet, such as <see cref="Remove-CimInstance"/>
|
|
|
|
/// might need to split the operation into multiple stages, i.e., query
|
|
|
|
/// CimInstance firstly, then remove the CimInstance resulted from query,
|
|
|
|
/// such that the temporary CimSession need to be shared between
|
|
|
|
/// multiple <see cref="CimSessionProxy"/> objects, introducing a
|
|
|
|
/// temporary session cache is necessary to control the lifetime of the
|
|
|
|
/// temporary CimSession objects.</para>
|
|
|
|
/// <para>
|
|
|
|
/// Once the reference count of the CimSession is decreased to 0,
|
|
|
|
/// then call Dispose on it.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
2020-11-21 15:29:44 +01:00
|
|
|
private static readonly Dictionary<CimSession, uint> temporarySessionCache = new();
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Add <see cref="CimSession"/> to temporary cache.
|
|
|
|
/// If CimSession already present in cache, then increase the refcount by 1,
|
|
|
|
/// otherwise insert it into the cache.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="session">CimSession to be added.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
internal static void AddCimSessionToTemporaryCache(CimSession session)
|
|
|
|
{
|
2018-06-25 23:37:09 +02:00
|
|
|
if (session != null)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
lock (temporarySessionCacheLock)
|
|
|
|
{
|
|
|
|
if (temporarySessionCache.ContainsKey(session))
|
|
|
|
{
|
|
|
|
temporarySessionCache[session]++;
|
|
|
|
DebugHelper.WriteLogEx(@"Increase cimsession ref count {0}", 1, temporarySessionCache[session]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
temporarySessionCache.Add(session, 1);
|
|
|
|
DebugHelper.WriteLogEx(@"Add cimsession to cache. Ref count {0}", 1, temporarySessionCache[session]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>Wrapper function to remove CimSession from cache</para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="session"></param>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="dispose">Whether need to dispose the <see cref="CimSession"/> object.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
private static void RemoveCimSessionFromTemporaryCache(CimSession session,
|
|
|
|
bool dispose)
|
|
|
|
{
|
2018-06-25 23:37:09 +02:00
|
|
|
if (session != null)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
bool removed = false;
|
|
|
|
lock (temporarySessionCacheLock)
|
|
|
|
{
|
|
|
|
if (temporarySessionCache.ContainsKey(session))
|
|
|
|
{
|
|
|
|
temporarySessionCache[session]--;
|
|
|
|
DebugHelper.WriteLogEx(@"Decrease cimsession ref count {0}", 1, temporarySessionCache[session]);
|
|
|
|
if (temporarySessionCache[session] == 0)
|
|
|
|
{
|
|
|
|
removed = true;
|
|
|
|
temporarySessionCache.Remove(session);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// there is a race condition that if
|
|
|
|
// one thread is waiting to add CimSession to cache,
|
|
|
|
// while current thread is removing the CimSession,
|
|
|
|
// then invalid CimSession may be added to cache.
|
|
|
|
// Ignored this scenario in CimCmdlet implementation,
|
|
|
|
// since the code inside cimcmdlet will not hit this
|
|
|
|
// scenario anyway.
|
|
|
|
if (removed && dispose)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx(@"Dispose cimsession ", 1);
|
|
|
|
session.Dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Remove <see cref="CimSession"/> from temporary cache.
|
|
|
|
/// If CimSession already present in cache, then decrease the refcount by 1,
|
|
|
|
/// otherwise ignore.
|
|
|
|
/// If refcount became 0, call dispose on the <see cref="CimSession"/> object.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="session">CimSession to be added.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
internal static void RemoveCimSessionFromTemporaryCache(CimSession session)
|
|
|
|
{
|
|
|
|
RemoveCimSessionFromTemporaryCache(session, true);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Event definitions
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Define an Event based on the NewActionHandler.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-07 12:30:19 +01:00
|
|
|
public event EventHandler<CmdletActionEventArgs> OnNewCmdletAction;
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Event triggered when a new operation is started.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-07 12:30:19 +01:00
|
|
|
public event EventHandler<OperationEventArgs> OnOperationCreated;
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Event triggered when a new operation is completed,
|
|
|
|
/// either success or failed.
|
|
|
|
/// </summary>
|
2020-11-07 12:30:19 +01:00
|
|
|
public event EventHandler<OperationEventArgs> OnOperationDeleted;
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region constructors
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxy"/> class.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// <remarks>
|
|
|
|
/// Then create wrapper object by given CimSessionProxy object.
|
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
public CimSessionProxy(CimSessionProxy proxy)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("protocol = {0}", 1, proxy.Protocol);
|
|
|
|
|
|
|
|
CreateSetSession(null, proxy.CimSession, null, proxy.OperationOptions, proxy.IsTemporaryCimSession);
|
2020-11-24 11:44:09 +01:00
|
|
|
this.Protocol = proxy.Protocol;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.OperationTimeout = proxy.OperationTimeout;
|
|
|
|
this.isDefaultSession = proxy.isDefaultSession;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxy"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
public CimSessionProxy(string computerName)
|
|
|
|
{
|
|
|
|
CreateSetSession(computerName, null, null, null, false);
|
2021-01-09 08:41:51 +01:00
|
|
|
this.isDefaultSession = computerName == ConstValue.NullComputerName;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxy"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name
|
|
|
|
/// and session options.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="sessionOptions"></param>
|
|
|
|
public CimSessionProxy(string computerName, CimSessionOptions sessionOptions)
|
|
|
|
{
|
|
|
|
CreateSetSession(computerName, null, sessionOptions, null, false);
|
2021-01-09 08:41:51 +01:00
|
|
|
this.isDefaultSession = computerName == ConstValue.NullComputerName;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxy"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name
|
|
|
|
/// and cimInstance. Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="cimInstance"></param>
|
|
|
|
public CimSessionProxy(string computerName, CimInstance cimInstance)
|
|
|
|
{
|
2016-08-28 23:46:20 +02:00
|
|
|
DebugHelper.WriteLogEx("ComputerName {0}; cimInstance.CimSessionInstanceID = {1}; cimInstance.CimSessionComputerName = {2}.",
|
2016-07-14 04:27:37 +02:00
|
|
|
0,
|
|
|
|
computerName,
|
|
|
|
cimInstance.GetCimSessionInstanceId(),
|
|
|
|
cimInstance.GetCimSessionComputerName());
|
|
|
|
|
|
|
|
if (computerName != ConstValue.NullComputerName)
|
|
|
|
{
|
|
|
|
CreateSetSession(computerName, null, null, null, false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.Assert(cimInstance != null, "Caller should verify cimInstance != null");
|
2017-01-16 22:31:14 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
// computerName is null, fallback to create session from cimInstance
|
|
|
|
CimSessionState state = CimSessionBase.GetCimSessionState();
|
|
|
|
if (state != null)
|
|
|
|
{
|
|
|
|
CimSession session = state.QuerySession(cimInstance.GetCimSessionInstanceId());
|
|
|
|
if (session != null)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("Found the session from cache with InstanceID={0}.", 0, cimInstance.GetCimSessionInstanceId());
|
|
|
|
CreateSetSession(null, session, null, null, false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2019-01-07 19:46:00 +01:00
|
|
|
string cimsessionComputerName = cimInstance.GetCimSessionComputerName();
|
2016-07-14 04:27:37 +02:00
|
|
|
CreateSetSession(cimsessionComputerName, null, null, null, false);
|
2021-01-09 08:41:51 +01:00
|
|
|
this.isDefaultSession = cimsessionComputerName == ConstValue.NullComputerName;
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
DebugHelper.WriteLogEx("Create a temp session with computerName = {0}.", 0, cimsessionComputerName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxy"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name,
|
2019-01-06 00:40:24 +01:00
|
|
|
/// session options.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="sessionOptions"></param>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="operOptions">Used when create async operation.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
public CimSessionProxy(string computerName, CimSessionOptions sessionOptions, CimOperationOptions operOptions)
|
|
|
|
{
|
|
|
|
CreateSetSession(computerName, null, sessionOptions, operOptions, false);
|
2021-01-09 08:41:51 +01:00
|
|
|
this.isDefaultSession = computerName == ConstValue.NullComputerName;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxy"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="operOptions">Used when create async operation.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
public CimSessionProxy(string computerName, CimOperationOptions operOptions)
|
|
|
|
{
|
|
|
|
CreateSetSession(computerName, null, null, operOptions, false);
|
2021-01-09 08:41:51 +01:00
|
|
|
this.isDefaultSession = computerName == ConstValue.NullComputerName;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxy"/> class.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// <remarks>
|
|
|
|
/// Create wrapper object by given session object.
|
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="session"></param>
|
|
|
|
public CimSessionProxy(CimSession session)
|
|
|
|
{
|
|
|
|
CreateSetSession(null, session, null, null, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxy"/> class.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// <remarks>
|
|
|
|
/// Create wrapper object by given session object.
|
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="session"></param>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="operOptions">Used when create async operation.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
public CimSessionProxy(CimSession session, CimOperationOptions operOptions)
|
|
|
|
{
|
|
|
|
CreateSetSession(null, session, null, operOptions, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Initialize CimSessionProxy object.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="session"></param>
|
|
|
|
/// <param name="sessionOptions"></param>
|
|
|
|
/// <param name="options"></param>
|
|
|
|
private void CreateSetSession(
|
|
|
|
string computerName,
|
|
|
|
CimSession cimSession,
|
|
|
|
CimSessionOptions sessionOptions,
|
|
|
|
CimOperationOptions operOptions,
|
|
|
|
bool temporaryCimSession)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("computername {0}; cimsession {1}; sessionOptions {2}; operationOptions {3}.", 0, computerName, cimSession, sessionOptions, operOptions);
|
|
|
|
|
|
|
|
lock (this.stateLock)
|
|
|
|
{
|
|
|
|
this.CancelOperation = null;
|
|
|
|
this.operation = null;
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
InitOption(operOptions);
|
2020-11-24 11:44:09 +01:00
|
|
|
this.Protocol = ProtocolType.Wsman;
|
|
|
|
this.IsTemporaryCimSession = temporaryCimSession;
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
if (cimSession != null)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.CimSession = cimSession;
|
2016-07-14 04:27:37 +02:00
|
|
|
CimSessionState state = CimSessionBase.GetCimSessionState();
|
|
|
|
if (state != null)
|
|
|
|
{
|
|
|
|
CimSessionWrapper wrapper = state.QuerySession(cimSession);
|
|
|
|
if (wrapper != null)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.Protocol = wrapper.GetProtocolType();
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (sessionOptions != null)
|
|
|
|
{
|
|
|
|
if (sessionOptions is DComSessionOptions)
|
|
|
|
{
|
|
|
|
string defaultComputerName = ConstValue.IsDefaultComputerName(computerName) ? ConstValue.NullComputerName : computerName;
|
2020-11-24 11:44:09 +01:00
|
|
|
this.CimSession = CimSession.Create(defaultComputerName, sessionOptions);
|
|
|
|
this.Protocol = ProtocolType.Dcom;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.CimSession = CimSession.Create(computerName, sessionOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.CimSession = CreateCimSessionByComputerName(computerName);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
this.IsTemporaryCimSession = true;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
if (this.IsTemporaryCimSession)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
AddCimSessionToTemporaryCache(this.CimSession);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
this.invocationContextObject = new InvocationContext(this);
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLog("Protocol {0}, Is temporary session ? {1}", 1, this.Protocol, this.IsTemporaryCimSession);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region set operation options
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Set timeout value (seconds) of the operation.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2021-07-28 21:39:14 +02:00
|
|
|
public uint OperationTimeout
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
2020-11-05 06:05:50 +01:00
|
|
|
get
|
|
|
|
{
|
2021-07-28 21:39:14 +02:00
|
|
|
return (uint)this.OperationOptions.Timeout.TotalSeconds;
|
2020-11-05 06:05:50 +01:00
|
|
|
}
|
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
set
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("OperationTimeout {0},", 0, value);
|
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.Timeout = TimeSpan.FromSeconds((double)value);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Set resource URI of the operation.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
public Uri ResourceUri
|
|
|
|
{
|
2020-11-05 06:05:50 +01:00
|
|
|
get
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
return this.OperationOptions.ResourceUri;
|
2020-11-05 06:05:50 +01:00
|
|
|
}
|
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
set
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("ResourceUri {0},", 0, value);
|
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.ResourceUri = value;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2017-01-16 22:31:14 +01:00
|
|
|
}
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
2016-08-26 22:46:03 +02:00
|
|
|
/// Enable/Disable the method result streaming,
|
2016-07-14 04:27:37 +02:00
|
|
|
/// it is enabled by default.
|
|
|
|
/// </summary>
|
|
|
|
public bool EnableMethodResultStreaming
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
return this.OperationOptions.EnableMethodResultStreaming;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
set
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("EnableMethodResultStreaming {0}", 0, value);
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.EnableMethodResultStreaming = value;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2016-08-26 22:46:03 +02:00
|
|
|
/// Enable/Disable prompt user streaming,
|
2016-07-14 04:27:37 +02:00
|
|
|
/// it is enabled by default.
|
|
|
|
/// </summary>
|
|
|
|
public bool EnablePromptUser
|
|
|
|
{
|
|
|
|
set
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("EnablePromptUser {0}", 0, value);
|
2020-01-31 23:56:22 +01:00
|
|
|
if (value)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.PromptUser = this.PromptUser;
|
2017-01-16 22:31:14 +01:00
|
|
|
}
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2017-01-16 22:31:14 +01:00
|
|
|
}
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Enable the pssemantics.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private void EnablePSSemantics()
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
// this.options.PromptUserForceFlag...
|
|
|
|
// this.options.WriteErrorMode
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.WriteErrorMode = CimCallbackMode.Inquire;
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
// !!!NOTES: Does not subscribe to PromptUser for CimCmdlets now
|
|
|
|
// since cmdlet does not provider an approach
|
|
|
|
// to let user select how to handle prompt message
|
|
|
|
// this can be enabled later if needed.
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.WriteError = this.WriteError;
|
|
|
|
this.OperationOptions.WriteMessage = this.WriteMessage;
|
|
|
|
this.OperationOptions.WriteProgress = this.WriteProgress;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Set keyonly property.
|
|
|
|
/// </summary>
|
|
|
|
public SwitchParameter KeyOnly
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
set { this.OperationOptions.KeysOnly = value.IsPresent; }
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Set Shallow flag.
|
|
|
|
/// </summary>
|
|
|
|
public SwitchParameter Shallow
|
|
|
|
{
|
|
|
|
set
|
|
|
|
{
|
|
|
|
if (value.IsPresent)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.Flags = CimOperationFlags.PolymorphismShallow;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.Flags = CimOperationFlags.None;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Initialize the operation option.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private void InitOption(CimOperationOptions operOptions)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
if (operOptions != null)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions = new CimOperationOptions(operOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2020-11-24 11:44:09 +01:00
|
|
|
else if (this.OperationOptions == null)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions = new CimOperationOptions();
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
this.EnableMethodResultStreaming = true;
|
|
|
|
this.EnablePSSemantics();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region misc operations
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Caller call Detach to retrieve the session
|
|
|
|
/// object and control the lifecycle of the CimSession object.
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
|
|
|
public CimSession Detach()
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
// Remove the CimSession from cache but don't dispose it
|
2020-11-24 11:44:09 +01:00
|
|
|
RemoveCimSessionFromTemporaryCache(this.CimSession, false);
|
|
|
|
CimSession sessionToReturn = this.CimSession;
|
|
|
|
this.CimSession = null;
|
|
|
|
this.IsTemporaryCimSession = false;
|
2016-07-14 04:27:37 +02:00
|
|
|
return sessionToReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2016-08-26 22:46:03 +02:00
|
|
|
/// Add a new operation to cache.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="operation"></param>
|
|
|
|
/// <param name="cancelObject"></param>
|
|
|
|
private void AddOperation(IObservable<object> operation)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
lock (this.stateLock)
|
|
|
|
{
|
|
|
|
Debug.Assert(this.Completed, "Caller should verify that there is no operation in progress");
|
|
|
|
this.operation = operation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Remove object from cache.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="operation"></param>
|
|
|
|
private void RemoveOperation(IObservable<object> operation)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
lock (this.stateLock)
|
|
|
|
{
|
2016-08-28 23:46:20 +02:00
|
|
|
Debug.Assert(this.operation == operation, "Caller should verify that the operation to remove is the operation in progress");
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
this.DisposeCancelOperation();
|
|
|
|
|
|
|
|
if (this.operation != null)
|
|
|
|
{
|
|
|
|
this.operation = null;
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
if (this.CimSession != null && this.ContextObject == null)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("Dispose this proxy object @ RemoveOperation");
|
|
|
|
this.Dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Trigger an event that new action available
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="action"></param>
|
|
|
|
protected void FireNewActionEvent(CimBaseAction action)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
2020-11-21 15:29:44 +01:00
|
|
|
CmdletActionEventArgs actionArgs = new(action);
|
2016-07-14 04:27:37 +02:00
|
|
|
if (!PreNewActionEvent(actionArgs))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-11-07 12:30:19 +01:00
|
|
|
EventHandler<CmdletActionEventArgs> temp = this.OnNewCmdletAction;
|
2016-07-14 04:27:37 +02:00
|
|
|
if (temp != null)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
temp(this.CimSession, actionArgs);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("Ignore action since OnNewCmdletAction is null.", 5);
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
this.PostNewActionEvent(actionArgs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Trigger an event that new operation is created
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="cancelOperation"></param>
|
|
|
|
/// <param name="operation"></param>
|
|
|
|
private void FireOperationCreatedEvent(
|
|
|
|
IDisposable cancelOperation,
|
|
|
|
IObservable<object> operation)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
2020-11-21 15:29:44 +01:00
|
|
|
OperationEventArgs args = new(
|
2016-07-14 04:27:37 +02:00
|
|
|
cancelOperation, operation, false);
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OnOperationCreated?.Invoke(this.CimSession, args);
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
this.PostOperationCreateEvent(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Trigger an event that an operation is deleted
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="operation"></param>
|
|
|
|
private void FireOperationDeletedEvent(
|
|
|
|
IObservable<object> operation,
|
|
|
|
bool success)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
this.WriteOperationCompleteMessage(this.operationName);
|
2020-11-21 15:29:44 +01:00
|
|
|
OperationEventArgs args = new(
|
2016-07-14 04:27:37 +02:00
|
|
|
null, operation, success);
|
|
|
|
PreOperationDeleteEvent(args);
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OnOperationDeleted?.Invoke(this.CimSession, args);
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
this.PostOperationDeleteEvent(args);
|
|
|
|
this.RemoveOperation(operation);
|
|
|
|
this.operationName = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region PSExtension callback functions
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// WriteMessage callback
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="channel"></param>
|
|
|
|
/// <param name="message"></param>
|
2021-07-28 21:39:14 +02:00
|
|
|
internal void WriteMessage(uint channel, string message)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("Channel = {0} message = {1}", 0, channel, message);
|
|
|
|
try
|
|
|
|
{
|
2020-11-21 15:29:44 +01:00
|
|
|
CimWriteMessage action = new(channel, message);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.FireNewActionEvent(action);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("{0}", 0, ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
2016-08-26 22:46:03 +02:00
|
|
|
/// Write operation start verbose message
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="operation"></param>
|
|
|
|
/// <param name="parameters"></param>
|
|
|
|
internal void WriteOperationStartMessage(string operation, Hashtable parameterList)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
2020-11-21 15:29:44 +01:00
|
|
|
StringBuilder parameters = new();
|
2016-07-14 04:27:37 +02:00
|
|
|
if (parameterList != null)
|
|
|
|
{
|
|
|
|
foreach (string key in parameterList.Keys)
|
|
|
|
{
|
|
|
|
if (parameters.Length > 0)
|
|
|
|
{
|
2020-10-30 08:07:18 +01:00
|
|
|
parameters.Append(',');
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
parameters.Append(string.Format(CultureInfo.CurrentUICulture, @"'{0}' = {1}", key, parameterList[key]));
|
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
string operationStartMessage = string.Format(CultureInfo.CurrentUICulture,
|
2020-06-15 20:00:02 +02:00
|
|
|
CimCmdletStrings.CimOperationStart,
|
2016-07-14 04:27:37 +02:00
|
|
|
operation,
|
|
|
|
(parameters.Length == 0) ? "null" : parameters.ToString());
|
2021-07-28 21:39:14 +02:00
|
|
|
WriteMessage((uint)CimWriteMessageChannel.Verbose, operationStartMessage);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Write operation complete verbose message
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="operation"></param>
|
|
|
|
internal void WriteOperationCompleteMessage(string operation)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
string operationCompleteMessage = string.Format(CultureInfo.CurrentUICulture,
|
2020-06-15 20:00:02 +02:00
|
|
|
CimCmdletStrings.CimOperationCompleted,
|
2016-07-14 04:27:37 +02:00
|
|
|
operation);
|
2021-07-28 21:39:14 +02:00
|
|
|
WriteMessage((uint)CimWriteMessageChannel.Verbose, operationCompleteMessage);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// WriteProgress callback
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="activity"></param>
|
|
|
|
/// <param name="currentOperation"></param>
|
|
|
|
/// <param name="statusDescription"></param>
|
|
|
|
/// <param name="percentageCompleted"></param>
|
|
|
|
/// <param name="secondsRemaining"></param>
|
|
|
|
public void WriteProgress(string activity,
|
|
|
|
string currentOperation,
|
|
|
|
string statusDescription,
|
2021-07-28 21:39:14 +02:00
|
|
|
uint percentageCompleted,
|
|
|
|
uint secondsRemaining)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("activity:{0}; currentOperation:{1}; percentageCompleted:{2}; secondsRemaining:{3}",
|
|
|
|
0, activity, currentOperation, percentageCompleted, secondsRemaining);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2020-11-21 15:29:44 +01:00
|
|
|
CimWriteProgress action = new(
|
2016-07-14 04:27:37 +02:00
|
|
|
activity,
|
|
|
|
(int)this.operationID,
|
|
|
|
currentOperation,
|
|
|
|
statusDescription,
|
|
|
|
percentageCompleted,
|
|
|
|
secondsRemaining);
|
|
|
|
this.FireNewActionEvent(action);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("{0}", 0, ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// WriteError callback
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="instance"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public CimResponseType WriteError(CimInstance instance)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("Error:{0}", 0, instance);
|
|
|
|
try
|
|
|
|
{
|
2020-11-21 15:29:44 +01:00
|
|
|
CimWriteError action = new(instance, this.invocationContextObject);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.FireNewActionEvent(action);
|
|
|
|
return action.GetResponse();
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("{0}", 0, ex);
|
|
|
|
return CimResponseType.NoToAll;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// PromptUser callback.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="message"></param>
|
|
|
|
/// <param name="prompt"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public CimResponseType PromptUser(string message, CimPromptType prompt)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("message:{0} prompt:{1}", 0, message, prompt);
|
|
|
|
try
|
|
|
|
{
|
2020-11-21 15:29:44 +01:00
|
|
|
CimPromptUser action = new(message, prompt);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.FireNewActionEvent(action);
|
|
|
|
return action.GetResponse();
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("{0}", 0, ex);
|
|
|
|
return CimResponseType.NoToAll;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Async result handler
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
2020-11-23 10:07:48 +01:00
|
|
|
/// Handle async event triggered by <see cref="CimResultObserver{T}"/>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
2018-12-29 04:25:49 +01:00
|
|
|
/// <param name="observer">Object triggered the event.</param>
|
|
|
|
/// <param name="resultArgs">Async result event argument.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
internal void ResultEventHandler(
|
|
|
|
object observer,
|
|
|
|
AsyncResultEventArgsBase resultArgs)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
switch (resultArgs.resultType)
|
|
|
|
{
|
|
|
|
case AsyncResultType.Completion:
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("ResultEventHandler::Completion", 4);
|
|
|
|
|
|
|
|
AsyncResultCompleteEventArgs args = resultArgs as AsyncResultCompleteEventArgs;
|
|
|
|
this.FireOperationDeletedEvent(args.observable, true);
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
break;
|
|
|
|
case AsyncResultType.Exception:
|
|
|
|
{
|
|
|
|
AsyncResultErrorEventArgs args = resultArgs as AsyncResultErrorEventArgs;
|
|
|
|
DebugHelper.WriteLog("ResultEventHandler::Exception {0}", 4, args.error);
|
|
|
|
|
2020-11-21 15:29:44 +01:00
|
|
|
using (CimWriteError action = new(args.error, this.invocationContextObject, args.context))
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
this.FireNewActionEvent(action);
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
this.FireOperationDeletedEvent(args.observable, false);
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
break;
|
|
|
|
case AsyncResultType.Result:
|
|
|
|
{
|
|
|
|
AsyncResultObjectEventArgs args = resultArgs as AsyncResultObjectEventArgs;
|
|
|
|
DebugHelper.WriteLog("ResultEventHandler::Result {0}", 4, args.resultObject);
|
|
|
|
object resultObject = args.resultObject;
|
|
|
|
if (!this.isDefaultSession)
|
|
|
|
{
|
|
|
|
AddShowComputerNameMarker(resultObject);
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
if (this.ObjectPreProcess != null)
|
|
|
|
{
|
|
|
|
resultObject = this.ObjectPreProcess.Process(resultObject);
|
|
|
|
}
|
|
|
|
#if DEBUG
|
|
|
|
resultObject = PostProcessCimInstance(resultObject);
|
|
|
|
#endif
|
2020-11-21 15:29:44 +01:00
|
|
|
CimWriteResultObject action = new(resultObject, this.ContextObject);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.FireNewActionEvent(action);
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2017-01-16 22:31:14 +01:00
|
|
|
/// This method adds a note property to <paramref name="o"/>,
|
2016-07-14 04:27:37 +02:00
|
|
|
/// which will cause the default PowerShell formatting and output
|
|
|
|
/// to include PSComputerName column/property in the display.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="o"></param>
|
|
|
|
private static void AddShowComputerNameMarker(object o)
|
|
|
|
{
|
2020-07-31 01:06:38 +02:00
|
|
|
if (o == null)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
PSObject pso = PSObject.AsPSObject(o);
|
2020-08-01 01:41:59 +02:00
|
|
|
if (pso.BaseObject is not CimInstance)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-11-21 15:29:44 +01:00
|
|
|
PSNoteProperty psShowComputerNameProperty = new(ConstValue.ShowComputerNameNoteProperty, true);
|
2016-07-14 04:27:37 +02:00
|
|
|
pso.Members.Add(psShowComputerNameProperty);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG
|
2020-11-02 08:43:04 +01:00
|
|
|
private static readonly bool isCliXmlTestabilityHookActive = GetIsCliXmlTestabilityHookActive();
|
2020-05-29 06:56:33 +02:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
private static bool GetIsCliXmlTestabilityHookActive()
|
|
|
|
{
|
|
|
|
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CDXML_CLIXML_TEST"));
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2020-11-24 08:01:01 +01:00
|
|
|
private static object PostProcessCimInstance(object resultObject)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
if (isCliXmlTestabilityHookActive && (resultObject is CimInstance))
|
|
|
|
{
|
|
|
|
string serializedForm = PSSerializer.Serialize(resultObject as CimInstance, depth: 1);
|
|
|
|
object deserializedObject = PSSerializer.Deserialize(serializedForm);
|
|
|
|
object returnObject = (deserializedObject is PSObject) ? (deserializedObject as PSObject).BaseObject : deserializedObject;
|
2018-12-24 08:01:44 +01:00
|
|
|
DebugHelper.WriteLogEx("Deserialized object is {0}, type {1}", 1, returnObject, returnObject.GetType());
|
2016-07-14 04:27:37 +02:00
|
|
|
return returnObject;
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
return resultObject;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Async operations
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// create a cim instance asynchronously
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="instance"></param>
|
|
|
|
public void CreateInstanceAsync(string namespaceName, CimInstance instance)
|
|
|
|
{
|
|
|
|
Debug.Assert(instance != null, "Caller should verify that instance != NULL.");
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLogEx("EnableMethodResultStreaming = {0}", 0, this.OperationOptions.EnableMethodResultStreaming);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = instance;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameCreateInstance;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"instance", instance);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncResult<CimInstance> asyncResult = this.CimSession.CreateInstanceAsync(namespaceName, instance, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimInstanceAsync(asyncResult, new CimResultContext(instance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Delete a cim instance asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="instance"></param>
|
|
|
|
public void DeleteInstanceAsync(string namespaceName, CimInstance instance)
|
|
|
|
{
|
|
|
|
Debug.Assert(instance != null, "Caller should verify that instance != NULL.");
|
|
|
|
DebugHelper.WriteLogEx("namespace = {0}; classname = {1};", 0, namespaceName, instance.CimSystemProperties.ClassName);
|
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = instance;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameDeleteInstance;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"instance", instance);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncStatus asyncResult = this.CimSession.DeleteInstanceAsync(namespaceName, instance, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeObjectAsync(asyncResult, new CimResultContext(instance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Get cim instance asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="instanceId"></param>
|
|
|
|
public void GetInstanceAsync(string namespaceName, CimInstance instance)
|
|
|
|
{
|
|
|
|
Debug.Assert(instance != null, "Caller should verify that instance != NULL.");
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLogEx("namespace = {0}; classname = {1}; keyonly = {2}", 0, namespaceName, instance.CimSystemProperties.ClassName, this.OperationOptions.KeysOnly);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = instance;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameGetInstance;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"instance", instance);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncResult<CimInstance> asyncResult = this.CimSession.GetInstanceAsync(namespaceName, instance, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimInstanceAsync(asyncResult, new CimResultContext(instance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Modify cim instance asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="instance"></param>
|
|
|
|
public void ModifyInstanceAsync(string namespaceName, CimInstance instance)
|
|
|
|
{
|
|
|
|
Debug.Assert(instance != null, "Caller should verify that instance != NULL.");
|
|
|
|
DebugHelper.WriteLogEx("namespace = {0}; classname = {1}", 0, namespaceName, instance.CimSystemProperties.ClassName);
|
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = instance;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameModifyInstance;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"instance", instance);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncResult<CimInstance> asyncResult = this.CimSession.ModifyInstanceAsync(namespaceName, instance, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeObjectAsync(asyncResult, new CimResultContext(instance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Enumerate cim instance associated with the
|
2019-01-06 00:40:24 +01:00
|
|
|
/// given instance asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="sourceInstance"></param>
|
|
|
|
/// <param name="associationClassName"></param>
|
|
|
|
/// <param name="resultClassName"></param>
|
|
|
|
/// <param name="sourceRole"></param>
|
|
|
|
/// <param name="resultRole"></param>
|
|
|
|
public void EnumerateAssociatedInstancesAsync(
|
|
|
|
string namespaceName,
|
|
|
|
CimInstance sourceInstance,
|
|
|
|
string associationClassName,
|
|
|
|
string resultClassName,
|
|
|
|
string sourceRole,
|
|
|
|
string resultRole)
|
|
|
|
{
|
|
|
|
Debug.Assert(sourceInstance != null, "Caller should verify that sourceInstance != NULL.");
|
|
|
|
DebugHelper.WriteLogEx("Instance class {0}, association class {1}", 0, sourceInstance.CimSystemProperties.ClassName, associationClassName);
|
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = sourceInstance;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameEnumerateAssociatedInstances;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"sourceInstance", sourceInstance);
|
|
|
|
this.operationParameters.Add(@"associationClassName", associationClassName);
|
|
|
|
this.operationParameters.Add(@"resultClassName", resultClassName);
|
|
|
|
this.operationParameters.Add(@"sourceRole", sourceRole);
|
|
|
|
this.operationParameters.Add(@"resultRole", resultRole);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncMultipleResults<CimInstance> asyncResult = this.CimSession.EnumerateAssociatedInstancesAsync(namespaceName, sourceInstance, associationClassName, resultClassName, sourceRole, resultRole, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimInstanceAsync(asyncResult, new CimResultContext(sourceInstance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Enumerate cim instance asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="className"></param>
|
|
|
|
public void EnumerateInstancesAsync(string namespaceName, string className)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLogEx("KeyOnly {0}", 0, this.OperationOptions.KeysOnly);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = null;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameEnumerateInstances;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"className", className);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncMultipleResults<CimInstance> asyncResult = this.CimSession.EnumerateInstancesAsync(namespaceName, className, this.OperationOptions);
|
2018-12-31 16:44:16 +01:00
|
|
|
string errorSource = string.Format(CultureInfo.CurrentUICulture, "{0}:{1}", namespaceName, className);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimInstanceAsync(asyncResult, new CimResultContext(errorSource));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Enumerate referencing instance associated with
|
|
|
|
/// the given instance asynchronously
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="sourceInstance"></param>
|
|
|
|
/// <param name="associationClassName"></param>
|
|
|
|
/// <param name="sourceRole"></param>
|
|
|
|
public void EnumerateReferencingInstancesAsync(
|
|
|
|
string namespaceName,
|
|
|
|
CimInstance sourceInstance,
|
|
|
|
string associationClassName,
|
|
|
|
string sourceRole)
|
|
|
|
{
|
|
|
|
this.CheckAvailability();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Query cim instance asynchronously
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="queryDialect"></param>
|
|
|
|
/// <param name="queryExpression"></param>
|
|
|
|
public void QueryInstancesAsync(
|
|
|
|
string namespaceName,
|
|
|
|
string queryDialect,
|
|
|
|
string queryExpression)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLogEx("KeyOnly = {0}", 0, this.OperationOptions.KeysOnly);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = null;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameQueryInstances;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"queryDialect", queryDialect);
|
|
|
|
this.operationParameters.Add(@"queryExpression", queryExpression);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncMultipleResults<CimInstance> asyncResult = this.CimSession.QueryInstancesAsync(namespaceName, queryDialect, queryExpression, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimInstanceAsync(asyncResult, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Enumerate cim class asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="className"></param>
|
|
|
|
public void EnumerateClassesAsync(string namespaceName)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("namespace {0}", 0, namespaceName);
|
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = null;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameEnumerateClasses;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncMultipleResults<CimClass> asyncResult = this.CimSession.EnumerateClassesAsync(namespaceName, null, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimClassAsync(asyncResult, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Enumerate cim class asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="className"></param>
|
|
|
|
public void EnumerateClassesAsync(string namespaceName, string className)
|
|
|
|
{
|
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = null;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameEnumerateClasses;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"className", className);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncMultipleResults<CimClass> asyncResult = this.CimSession.EnumerateClassesAsync(namespaceName, className, this.OperationOptions);
|
2018-12-31 16:44:16 +01:00
|
|
|
string errorSource = string.Format(CultureInfo.CurrentUICulture, "{0}:{1}", namespaceName, className);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimClassAsync(asyncResult, new CimResultContext(errorSource));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Get cim class asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="className"></param>
|
|
|
|
public void GetClassAsync(string namespaceName, string className)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("namespace = {0}, className = {1}", 0, namespaceName, className);
|
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = null;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameGetClass;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"className", className);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncResult<CimClass> asyncResult = this.CimSession.GetClassAsync(namespaceName, className, this.OperationOptions);
|
2018-12-31 16:44:16 +01:00
|
|
|
string errorSource = string.Format(CultureInfo.CurrentUICulture, "{0}:{1}", namespaceName, className);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimClassAsync(asyncResult, new CimResultContext(errorSource));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Invoke method of a given cim instance asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="instance"></param>
|
|
|
|
/// <param name="methodName"></param>
|
|
|
|
/// <param name="methodParameters"></param>
|
|
|
|
public void InvokeMethodAsync(
|
|
|
|
string namespaceName,
|
|
|
|
CimInstance instance,
|
|
|
|
string methodName,
|
|
|
|
CimMethodParametersCollection methodParameters)
|
|
|
|
{
|
|
|
|
Debug.Assert(instance != null, "Caller should verify that instance != NULL.");
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLogEx("EnableMethodResultStreaming = {0}", 0, this.OperationOptions.EnableMethodResultStreaming);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = instance;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameInvokeMethod;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"instance", instance);
|
|
|
|
this.operationParameters.Add(@"methodName", methodName);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncMultipleResults<CimMethodResultBase> asyncResult = this.CimSession.InvokeMethodAsync(namespaceName, instance, methodName, methodParameters, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimInvokeMethodResultAsync(asyncResult, instance.CimSystemProperties.ClassName, methodName, new CimResultContext(instance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Invoke static method of a given class asynchronously.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="className"></param>
|
|
|
|
/// <param name="methodName"></param>
|
|
|
|
/// <param name="methodParameters"></param>
|
|
|
|
public void InvokeMethodAsync(
|
|
|
|
string namespaceName,
|
|
|
|
string className,
|
|
|
|
string methodName,
|
|
|
|
CimMethodParametersCollection methodParameters)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLogEx("EnableMethodResultStreaming = {0}", 0, this.OperationOptions.EnableMethodResultStreaming);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = null;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameInvokeMethod;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"className", className);
|
|
|
|
this.operationParameters.Add(@"methodName", methodName);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
2020-11-24 11:44:09 +01:00
|
|
|
CimAsyncMultipleResults<CimMethodResultBase> asyncResult = this.CimSession.InvokeMethodAsync(namespaceName, className, methodName, methodParameters, this.OperationOptions);
|
2018-12-31 16:44:16 +01:00
|
|
|
string errorSource = string.Format(CultureInfo.CurrentUICulture, "{0}:{1}", namespaceName, className);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimInvokeMethodResultAsync(asyncResult, className, methodName, new CimResultContext(errorSource));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Subscribe to cim indication asynchronously
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="namespaceName"></param>
|
|
|
|
/// <param name="queryDialect"></param>
|
|
|
|
/// <param name="queryExpression"></param>
|
|
|
|
public void SubscribeAsync(
|
|
|
|
string namespaceName,
|
|
|
|
string queryDialect,
|
|
|
|
string queryExpression)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("QueryDialect = '{0}'; queryExpression = '{1}'", 0, queryDialect, queryExpression);
|
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = null;
|
2020-06-15 20:00:02 +02:00
|
|
|
this.operationName = CimCmdletStrings.CimOperationNameSubscribeIndication;
|
2016-07-14 04:27:37 +02:00
|
|
|
this.operationParameters.Clear();
|
|
|
|
this.operationParameters.Add(@"namespaceName", namespaceName);
|
|
|
|
this.operationParameters.Add(@"queryDialect", queryDialect);
|
|
|
|
this.operationParameters.Add(@"queryExpression", queryExpression);
|
|
|
|
this.WriteOperationStartMessage(this.operationName, this.operationParameters);
|
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.Flags |= CimOperationFlags.ReportOperationStarted;
|
|
|
|
CimAsyncMultipleResults<CimSubscriptionResult> asyncResult = this.CimSession.SubscribeAsync(namespaceName, queryDialect, queryExpression, this.OperationOptions);
|
2016-07-14 04:27:37 +02:00
|
|
|
ConsumeCimSubscriptionResultAsync(asyncResult, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Test connection asynchronously
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
public void TestConnectionAsync()
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("Start test connection", 0);
|
|
|
|
this.CheckAvailability();
|
2020-11-24 11:44:09 +01:00
|
|
|
this.TargetCimInstance = null;
|
|
|
|
CimAsyncResult<CimInstance> asyncResult = this.CimSession.TestConnectionAsync();
|
2016-07-14 04:27:37 +02:00
|
|
|
// ignore the test connection result objects
|
|
|
|
ConsumeCimInstanceAsync(asyncResult, true, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region pre action APIs
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called before new action event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected virtual bool PreNewActionEvent(CmdletActionEventArgs args)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called before operation delete event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected virtual void PreOperationDeleteEvent(OperationEventArgs args)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region post action APIs
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called after new action event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected virtual void PostNewActionEvent(CmdletActionEventArgs args)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called after operation create event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected virtual void PostOperationCreateEvent(OperationEventArgs args)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called after operation delete event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected virtual void PostOperationDeleteEvent(OperationEventArgs args)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region members
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Unique operation ID
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
private long operationID;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The CimSession object managed by this proxy object,
|
|
|
|
/// which is either created by constructor OR passed in by caller.
|
|
|
|
/// The session will be closed while disposing this proxy object
|
|
|
|
/// if it is created by constuctor.
|
|
|
|
/// </summary>
|
2020-11-24 11:44:09 +01:00
|
|
|
internal CimSession CimSession { get; private set; }
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The current CimInstance object, against which issued
|
2019-01-06 00:40:24 +01:00
|
|
|
/// current operation, it could be null.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-27 09:17:38 +01:00
|
|
|
internal CimInstance TargetCimInstance { get; private set; }
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
internal bool IsTemporaryCimSession { get; private set; }
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The CimOperationOptions object, which specifies the options
|
|
|
|
/// of the operation against the session object.
|
|
|
|
/// Caller can control the timeout, method streaming support, and
|
|
|
|
/// extended ps semantics support, etc.
|
|
|
|
/// The setting MUST be set before start new operation on the
|
|
|
|
/// this proxy object.
|
|
|
|
/// </summary>
|
2020-11-24 11:44:09 +01:00
|
|
|
internal CimOperationOptions OperationOptions { get; private set; }
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// All operations completed.
|
|
|
|
/// </summary>
|
|
|
|
private bool Completed
|
|
|
|
{
|
2020-07-31 01:06:38 +02:00
|
|
|
get { return this.operation == null; }
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Lock object used to lock
|
2019-01-06 00:40:24 +01:00
|
|
|
/// operation & cancelOperation members.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-21 15:29:44 +01:00
|
|
|
private readonly object stateLock = new();
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// The operation issued by cimSession.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private IObservable<object> operation;
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// The current operation name.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private string operationName;
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// The current operation parameters.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-21 15:29:44 +01:00
|
|
|
private readonly Hashtable operationParameters = new();
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Handler used to cancel operation.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private IDisposable _cancelOperation;
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// CancelOperation disposed flag.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private int _cancelOperationDisposed = 0;
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Dispose the cancel operation.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private void DisposeCancelOperation()
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("CancelOperation Disposed = {0}", 0, this._cancelOperationDisposed);
|
|
|
|
if (Interlocked.CompareExchange(ref this._cancelOperationDisposed, 1, 0) == 0)
|
|
|
|
{
|
|
|
|
if (this._cancelOperation != null)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("CimSessionProxy::Dispose async operation.", 4);
|
|
|
|
this._cancelOperation.Dispose();
|
|
|
|
this._cancelOperation = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Set the cancel operation.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private IDisposable CancelOperation
|
|
|
|
{
|
2020-11-05 06:05:50 +01:00
|
|
|
get
|
|
|
|
{
|
|
|
|
return this._cancelOperation;
|
|
|
|
}
|
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
set
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
this._cancelOperation = value;
|
|
|
|
Interlocked.Exchange(ref this._cancelOperationDisposed, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Current protocol name
|
2019-01-06 00:40:24 +01:00
|
|
|
/// DCOM or WSMAN.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-24 11:44:09 +01:00
|
|
|
internal ProtocolType Protocol { get; private set; }
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Cross operation context object.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-24 11:44:09 +01:00
|
|
|
internal XOperationContextBase ContextObject { get; set; }
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// Invocation context object.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private InvocationContext invocationContextObject;
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-09 22:07:41 +01:00
|
|
|
/// A preprocess object to pre-processing the result object,
|
2016-07-14 04:27:37 +02:00
|
|
|
/// for example, adding PSTypeName, etc.
|
|
|
|
/// </summary>
|
2020-11-24 11:44:09 +01:00
|
|
|
internal IObjectPreProcess ObjectPreProcess { get; set; }
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
/// <summary>
|
2020-11-24 05:35:46 +01:00
|
|
|
/// <see cref="isDefaultSession"/> is <see langword="true"/> if this <see cref="CimSessionProxy"/> was
|
2017-01-16 22:31:14 +01:00
|
|
|
/// created to handle the "default" session, in cases where cmdlets are invoked without
|
2016-07-14 04:27:37 +02:00
|
|
|
/// ComputerName and/or CimSession parameters.
|
|
|
|
/// </summary>
|
2020-11-02 08:43:04 +01:00
|
|
|
private readonly bool isDefaultSession;
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region IDisposable
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// IDisposable interface.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
private int _disposed;
|
|
|
|
|
|
|
|
// Implement IDisposable.
|
|
|
|
// Do not make this method virtual.
|
|
|
|
// A derived class should not be able to override this method.
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
Dispose(true);
|
|
|
|
// This object will be cleaned up by the Dispose method.
|
2016-08-26 22:46:03 +02:00
|
|
|
// Therefore, you should call GC.SuppressFinalize to
|
2016-07-14 04:27:37 +02:00
|
|
|
// take this object off the finalization queue
|
|
|
|
// and prevent finalization code for this object
|
|
|
|
// from executing a second time.
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dispose(bool disposing) executes in two distinct scenarios.
|
|
|
|
// If disposing equals true, the method has been called directly
|
|
|
|
// or indirectly by a user's code. Managed and unmanaged resources
|
|
|
|
// can be disposed.
|
|
|
|
// If disposing equals false, the method has been called by the
|
|
|
|
// runtime from inside the finalizer and you should not reference
|
|
|
|
// other objects. Only unmanaged resources can be disposed.
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("Disposed = {0}", 0, this.IsDisposed);
|
|
|
|
|
|
|
|
if (Interlocked.CompareExchange(ref this._disposed, 1, 0) == 0)
|
|
|
|
{
|
|
|
|
if (disposing)
|
|
|
|
{
|
|
|
|
// Dispose managed resources.
|
|
|
|
this.DisposeCancelOperation();
|
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
if (this.OperationOptions != null)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.OperationOptions.Dispose();
|
|
|
|
this.OperationOptions = null;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
DisposeTemporaryCimSession();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool IsDisposed
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this._disposed == 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Dispose temporary <see cref="CimSession"/>.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
private void DisposeTemporaryCimSession()
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
if (this.IsTemporaryCimSession && this.CimSession != null)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
// remove the cimsession from temporary cache
|
2020-11-24 11:44:09 +01:00
|
|
|
RemoveCimSessionFromTemporaryCache(this.CimSession);
|
|
|
|
this.IsTemporaryCimSession = false;
|
|
|
|
this.CimSession = null;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region helper methods
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Consume the results of async operations
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="asyncResult"></param>
|
|
|
|
/// <param name="cimResultContext"></param>
|
|
|
|
protected void ConsumeCimInstanceAsync(IObservable<CimInstance> asyncResult,
|
|
|
|
CimResultContext cimResultContext)
|
|
|
|
{
|
|
|
|
ConsumeCimInstanceAsync(asyncResult, false, cimResultContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Consume the CimInstance results of async operations.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="asyncResult"></param>
|
|
|
|
/// <param name="ignoreResultObjects"></param>
|
|
|
|
/// <param name="cimResultContext"></param>
|
|
|
|
protected void ConsumeCimInstanceAsync(
|
|
|
|
IObservable<CimInstance> asyncResult,
|
|
|
|
bool ignoreResultObjects,
|
|
|
|
CimResultContext cimResultContext)
|
|
|
|
{
|
|
|
|
CimResultObserver<CimInstance> observer;
|
|
|
|
if (ignoreResultObjects)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
observer = new IgnoreResultObserver(this.CimSession, asyncResult);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
observer = new CimResultObserver<CimInstance>(this.CimSession, asyncResult, cimResultContext);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
observer.OnNewResult += this.ResultEventHandler;
|
|
|
|
this.operationID = Interlocked.Increment(ref gOperationCounter);
|
|
|
|
this.AddOperation(asyncResult);
|
|
|
|
this.CancelOperation = asyncResult.Subscribe(observer);
|
|
|
|
this.FireOperationCreatedEvent(this.CancelOperation, asyncResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Consume the results of async operations
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="asyncResult"></param>
|
|
|
|
/// <param name="cimResultContext"></param>
|
|
|
|
protected void ConsumeObjectAsync(IObservable<object> asyncResult,
|
|
|
|
CimResultContext cimResultContext)
|
|
|
|
{
|
2020-11-21 15:29:44 +01:00
|
|
|
CimResultObserver<object> observer = new(
|
2020-11-24 11:44:09 +01:00
|
|
|
this.CimSession, asyncResult, cimResultContext);
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
observer.OnNewResult += this.ResultEventHandler;
|
|
|
|
this.operationID = Interlocked.Increment(ref gOperationCounter);
|
|
|
|
this.AddOperation(asyncResult);
|
|
|
|
this.CancelOperation = asyncResult.Subscribe(observer);
|
|
|
|
DebugHelper.WriteLog("FireOperationCreatedEvent");
|
|
|
|
this.FireOperationCreatedEvent(this.CancelOperation, asyncResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Consume the <see cref="CimClass"/> of async operations
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="asyncResult"></param>
|
|
|
|
/// <param name="cimResultContext"></param>
|
|
|
|
protected void ConsumeCimClassAsync(IObservable<CimClass> asyncResult,
|
|
|
|
CimResultContext cimResultContext)
|
|
|
|
{
|
2020-11-21 15:29:44 +01:00
|
|
|
CimResultObserver<CimClass> observer = new(
|
2020-11-24 11:44:09 +01:00
|
|
|
this.CimSession, asyncResult, cimResultContext);
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
observer.OnNewResult += this.ResultEventHandler;
|
|
|
|
this.operationID = Interlocked.Increment(ref gOperationCounter);
|
|
|
|
this.AddOperation(asyncResult);
|
|
|
|
this.CancelOperation = asyncResult.Subscribe(observer);
|
|
|
|
this.FireOperationCreatedEvent(this.CancelOperation, asyncResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Consume the <see cref="CimSubscriptionResult"/> of async operations
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="asyncResult"></param>
|
|
|
|
/// <param name="cimResultContext"></param>
|
|
|
|
protected void ConsumeCimSubscriptionResultAsync(
|
|
|
|
IObservable<CimSubscriptionResult> asyncResult,
|
|
|
|
CimResultContext cimResultContext)
|
|
|
|
{
|
2020-11-21 15:29:44 +01:00
|
|
|
CimSubscriptionResultObserver observer = new(
|
2020-11-24 11:44:09 +01:00
|
|
|
this.CimSession, asyncResult, cimResultContext);
|
2016-07-14 04:27:37 +02:00
|
|
|
observer.OnNewResult += this.ResultEventHandler;
|
|
|
|
this.operationID = Interlocked.Increment(ref gOperationCounter);
|
|
|
|
this.AddOperation(asyncResult);
|
|
|
|
this.CancelOperation = asyncResult.Subscribe(observer);
|
|
|
|
this.FireOperationCreatedEvent(this.CancelOperation, asyncResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Consume the <see cref="CimMethodResultBase"/> of async operations
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="asyncResult"></param>
|
|
|
|
/// <param name="className"></param>
|
|
|
|
/// <param name="methodName"></param>
|
|
|
|
/// <param name="cimResultContext"></param>
|
|
|
|
protected void ConsumeCimInvokeMethodResultAsync(
|
|
|
|
IObservable<CimMethodResultBase> asyncResult,
|
2019-01-07 19:46:00 +01:00
|
|
|
string className,
|
|
|
|
string methodName,
|
2016-07-14 04:27:37 +02:00
|
|
|
CimResultContext cimResultContext)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
CimMethodResultObserver observer = new(this.CimSession, asyncResult, cimResultContext)
|
2020-01-31 23:56:22 +01:00
|
|
|
{
|
|
|
|
ClassName = className,
|
|
|
|
MethodName = methodName
|
|
|
|
};
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
observer.OnNewResult += this.ResultEventHandler;
|
|
|
|
this.operationID = Interlocked.Increment(ref gOperationCounter);
|
|
|
|
this.AddOperation(asyncResult);
|
|
|
|
this.CancelOperation = asyncResult.Subscribe(observer);
|
|
|
|
this.FireOperationCreatedEvent(this.CancelOperation, asyncResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Check whether current proxy object is available
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
private void CheckAvailability()
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
AssertSession();
|
|
|
|
lock (this.stateLock)
|
|
|
|
{
|
|
|
|
if (!this.Completed)
|
|
|
|
{
|
2020-06-15 20:00:02 +02:00
|
|
|
throw new InvalidOperationException(CimCmdletStrings.OperationInProgress);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLog("KeyOnly {0},", 1, this.OperationOptions.KeysOnly);
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Check the wrapped <see cref="CimSession"/> object
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
private void AssertSession()
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
if (this.IsDisposed || (this.CimSession == null))
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
DebugHelper.WriteLogEx("Invalid CimSessionProxy object, disposed? {0}; session object {1}", 1, this.IsDisposed, this.CimSession);
|
2016-07-14 04:27:37 +02:00
|
|
|
throw new ObjectDisposedException(this.ToString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Create <see cref="CimSessionOptions"/> based on the given computerName
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
|
|
|
private CimSession CreateCimSessionByComputerName(string computerName)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("ComputerName {0}", 0, computerName);
|
|
|
|
|
|
|
|
CimSessionOptions option = CreateCimSessionOption(computerName, 0, null);
|
|
|
|
if (option is DComSessionOptions)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("Create dcom cimSession");
|
2020-11-24 11:44:09 +01:00
|
|
|
this.Protocol = ProtocolType.Dcom;
|
2016-07-14 04:27:37 +02:00
|
|
|
return CimSession.Create(ConstValue.NullComputerName, option);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("Create wsman cimSession");
|
|
|
|
return CimSession.Create(computerName, option);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Create <see cref="CimSessionOptions"/> based on the given computerName,
|
|
|
|
/// timeout and credential
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="timeout"></param>
|
|
|
|
/// <param name="credential"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
internal static CimSessionOptions CreateCimSessionOption(string computerName,
|
2021-07-28 21:39:14 +02:00
|
|
|
uint timeout, CimCredential credential)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
CimSessionOptions option;
|
|
|
|
if (ConstValue.IsDefaultComputerName(computerName))
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("<<<<<<<<<< Use protocol DCOM {0}", 1, computerName);
|
|
|
|
option = new DComSessionOptions();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("<<<<<<<<<< Use protocol WSMAN {0}", 1, computerName);
|
|
|
|
option = new WSManSessionOptions();
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
if (timeout != 0)
|
|
|
|
{
|
|
|
|
option.Timeout = TimeSpan.FromSeconds((double)timeout);
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
if (credential != null)
|
|
|
|
{
|
|
|
|
option.AddDestinationCredentials(credential);
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
DebugHelper.WriteLogEx("returned option :{0}.", 1, option);
|
|
|
|
return option;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2019-01-06 02:51:20 +01:00
|
|
|
}
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
#region class CimSessionProxyTestConnection
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Write session to pipeline after test connection success
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
internal class CimSessionProxyTestConnection : CimSessionProxy
|
|
|
|
{
|
|
|
|
#region constructors
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxyTestConnection"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name
|
|
|
|
/// and session options.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="sessionOptions"></param>
|
|
|
|
public CimSessionProxyTestConnection(string computerName, CimSessionOptions sessionOptions)
|
|
|
|
: base(computerName, sessionOptions)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region pre action APIs
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called after operation delete event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected override void PreOperationDeleteEvent(OperationEventArgs args)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx("test connection result {0}", 0, args.success);
|
|
|
|
|
|
|
|
if (args.success)
|
|
|
|
{
|
|
|
|
// test connection success, write session object to pipeline
|
2020-11-21 15:29:44 +01:00
|
|
|
CimWriteResultObject result = new(this.CimSession, this.ContextObject);
|
2016-07-14 04:27:37 +02:00
|
|
|
this.FireNewActionEvent(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region class CimSessionProxyGetCimClass
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Write CimClass to pipeline if the CimClass satisfied
|
|
|
|
/// the given conditions
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
internal class CimSessionProxyGetCimClass : CimSessionProxy
|
|
|
|
{
|
|
|
|
#region constructors
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxyGetCimClass"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
public CimSessionProxyGetCimClass(string computerName)
|
|
|
|
: base(computerName)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxyGetCimClass"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name
|
|
|
|
/// and session options.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="sessionOptions"></param>
|
|
|
|
public CimSessionProxyGetCimClass(CimSession session)
|
|
|
|
: base(session)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region pre action APIs
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called before new action event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected override bool PreNewActionEvent(CmdletActionEventArgs args)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
2020-08-01 01:41:59 +02:00
|
|
|
if (args.Action is not CimWriteResultObject)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
// allow all other actions
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
CimWriteResultObject writeResultObject = args.Action as CimWriteResultObject;
|
2020-11-05 17:58:48 +01:00
|
|
|
if (!(writeResultObject.Result is CimClass cimClass))
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
DebugHelper.WriteLog("class name = {0}", 1, cimClass.CimSystemProperties.ClassName);
|
|
|
|
|
|
|
|
CimGetCimClassContext context = this.ContextObject as CimGetCimClassContext;
|
|
|
|
Debug.Assert(context != null, "Caller should verify that CimGetCimClassContext != NULL.");
|
|
|
|
|
|
|
|
WildcardPattern pattern;
|
|
|
|
if (WildcardPattern.ContainsWildcardCharacters(context.ClassName))
|
|
|
|
{
|
|
|
|
pattern = new WildcardPattern(context.ClassName, WildcardOptions.IgnoreCase);
|
|
|
|
if (!pattern.IsMatch(cimClass.CimSystemProperties.ClassName))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
if (context.PropertyName != null)
|
|
|
|
{
|
|
|
|
bool match = false;
|
|
|
|
if (cimClass.CimClassProperties != null)
|
|
|
|
{
|
2019-07-10 18:06:34 +02:00
|
|
|
pattern = new WildcardPattern(context.PropertyName, WildcardOptions.IgnoreCase);
|
2016-07-14 04:27:37 +02:00
|
|
|
foreach (CimPropertyDeclaration decl in cimClass.CimClassProperties)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("--- property name : {0}", 1, decl.Name);
|
|
|
|
if (pattern.IsMatch(decl.Name))
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!match)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("Property name does not match: {0}", 1, context.PropertyName);
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
if (context.MethodName != null)
|
|
|
|
{
|
|
|
|
bool match = false;
|
|
|
|
if (cimClass.CimClassMethods != null)
|
|
|
|
{
|
2019-07-10 18:06:34 +02:00
|
|
|
pattern = new WildcardPattern(context.MethodName, WildcardOptions.IgnoreCase);
|
2016-07-14 04:27:37 +02:00
|
|
|
foreach (CimMethodDeclaration decl in cimClass.CimClassMethods)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("--- method name : {0}", 1, decl.Name);
|
|
|
|
if (pattern.IsMatch(decl.Name))
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!match)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("Method name does not match: {0}", 1, context.MethodName);
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-07-14 04:27:37 +02:00
|
|
|
if (context.QualifierName != null)
|
|
|
|
{
|
|
|
|
bool match = false;
|
|
|
|
if (cimClass.CimClassQualifiers != null)
|
|
|
|
{
|
2019-07-10 18:06:34 +02:00
|
|
|
pattern = new WildcardPattern(context.QualifierName, WildcardOptions.IgnoreCase);
|
2016-07-14 04:27:37 +02:00
|
|
|
foreach (CimQualifier qualifier in cimClass.CimClassQualifiers)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLog("--- qualifier name : {0}", 1, qualifier.Name);
|
|
|
|
if (pattern.IsMatch(qualifier.Name))
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!match)
|
|
|
|
{
|
2016-08-28 23:46:20 +02:00
|
|
|
DebugHelper.WriteLog("Qualifier name does not match: {0}", 1, context.QualifierName);
|
2016-07-14 04:27:37 +02:00
|
|
|
return match;
|
|
|
|
}
|
|
|
|
}
|
2018-12-24 07:20:06 +01:00
|
|
|
|
2016-08-26 22:46:03 +02:00
|
|
|
DebugHelper.WriteLog("CimClass '{0}' is qualified.", 1, cimClass.CimSystemProperties.ClassName);
|
2016-07-14 04:27:37 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region class CimSessionProxyNewCimInstance
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Get full <see cref="CimInstance"/> if create successfully.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
internal class CimSessionProxyNewCimInstance : CimSessionProxy
|
|
|
|
{
|
|
|
|
#region constructors
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxyNewCimInstance"/> class.
|
|
|
|
/// <summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
public CimSessionProxyNewCimInstance(string computerName, CimNewCimInstance operation)
|
|
|
|
: base(computerName)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.NewCimInstanceOperation = operation;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxyNewCimInstance"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name
|
|
|
|
/// and session options.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="sessionOptions"></param>
|
|
|
|
public CimSessionProxyNewCimInstance(CimSession session, CimNewCimInstance operation)
|
|
|
|
: base(session)
|
|
|
|
{
|
2020-11-24 11:44:09 +01:00
|
|
|
this.NewCimInstanceOperation = operation;
|
2016-07-14 04:27:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region pre action APIs
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called before new action event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected override bool PreNewActionEvent(CmdletActionEventArgs args)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
2020-08-01 01:41:59 +02:00
|
|
|
if (args.Action is not CimWriteResultObject)
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
// allow all other actions
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
CimWriteResultObject writeResultObject = args.Action as CimWriteResultObject;
|
2020-11-05 17:58:48 +01:00
|
|
|
if (!(writeResultObject.Result is CimInstance cimInstance))
|
2016-07-14 04:27:37 +02:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
DebugHelper.WriteLog("Going to read CimInstance classname = {0}; namespace = {1}", 1, cimInstance.CimSystemProperties.ClassName, cimInstance.CimSystemProperties.Namespace);
|
|
|
|
this.NewCimInstanceOperation.GetCimInstance(cimInstance, this.ContextObject);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region private members
|
|
|
|
|
2020-11-27 09:17:38 +01:00
|
|
|
internal CimNewCimInstance NewCimInstanceOperation { get; }
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region class CimSessionProxyNewCimInstance
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Support PassThru for set-ciminstance.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
internal class CimSessionProxySetCimInstance : CimSessionProxy
|
|
|
|
{
|
|
|
|
#region constructors
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxySetCimInstance"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given <see cref="CimSessionProxy"/> object.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="originalProxy"><see cref="CimSessionProxy"/> object to clone.</param>
|
2018-12-28 12:39:06 +01:00
|
|
|
/// <param name="passThru">PassThru, true means output the modified instance; otherwise does not output.</param>
|
2016-07-14 04:27:37 +02:00
|
|
|
public CimSessionProxySetCimInstance(CimSessionProxy originalProxy, bool passThru)
|
|
|
|
: base(originalProxy)
|
|
|
|
{
|
|
|
|
this.passThru = passThru;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxySetCimInstance"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="cimInstance"></param>
|
|
|
|
/// <param name="passThru"></param>
|
|
|
|
public CimSessionProxySetCimInstance(string computerName,
|
|
|
|
CimInstance cimInstance,
|
|
|
|
bool passThru)
|
|
|
|
: base(computerName, cimInstance)
|
|
|
|
{
|
|
|
|
this.passThru = passThru;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2020-11-27 09:07:58 +01:00
|
|
|
/// Initializes a new instance of the <see cref="CimSessionProxySetCimInstance"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// Create <see cref="CimSession"/> by given computer name
|
|
|
|
/// and session options.
|
|
|
|
/// Then create wrapper object.
|
2020-11-27 09:07:58 +01:00
|
|
|
/// </remarks>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="sessionOptions"></param>
|
|
|
|
public CimSessionProxySetCimInstance(CimSession session, bool passThru)
|
|
|
|
: base(session)
|
|
|
|
{
|
|
|
|
this.passThru = passThru;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region pre action APIs
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Called before new action event.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="args"></param>
|
|
|
|
protected override bool PreNewActionEvent(CmdletActionEventArgs args)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
if ((!this.passThru) && (args.Action is CimWriteResultObject))
|
|
|
|
{
|
|
|
|
// filter out any output object
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region private members
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-06 00:40:24 +01:00
|
|
|
/// Ture indicates need to output the modified result.
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
2020-11-02 08:43:04 +01:00
|
|
|
private readonly bool passThru = false;
|
2016-07-14 04:27:37 +02:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
2019-01-06 02:51:20 +01:00
|
|
|
}
|