Очевидно, что во втором примере, где вы не производите от PSVariable, вы не можете ожидать, что переменная $ ActiveCell изменится со значением свойства ActiveCell, поскольку вы захватываете его значение только один раз.
Я не верю, что наследование от PSVariable является поддерживаемым сценарием, но он работает, и я сделал это, чтобы добавить такие переменные, как $Now
и $Today
.
Может быть, лучше представить переменную $ Application в сценарии PowerShell вместо различных свойств объекта Application. Плюсом этого является то, что вам не нужно создавать кучу автоматических переменных, и сценарии PowerShell могут получить доступ ко всему, что может предложить объект Application, используя $ Application.ActiveCell. Другим преимуществом является то, что она вообще не должна быть автоматической переменной, потому что ссылка на объект приложения никогда не изменится.
Сказав все это, я включил подкласс PSVariable, который я использую время от времени, который принимает ScriptBlock для метода получения и установки. Это позволяет мне определять автоматические переменные из PowerShell, не требуя отдельного производного класса для каждого.
using System;
using System.Management.Automation;
namespace Einstein.PowerShell
{
public sealed class DynamicVariable : PSVariable
{
#region Constructors
/// <summary>
/// </summary>
public DynamicVariable(string name, ScriptBlock onGet)
: this(name, onGet, null)
{
}
/// <summary>
/// </summary>
public DynamicVariable(string name, ScriptBlock onGet, ScriptBlock onSet)
: base(name, null, ScopedItemOptions.AllScope)
{
OnGet = onGet;
OnSet = onSet;
}
#endregion
#region Properties
/// <summary>
/// The ScriptBlock that runs to get the value of the variable.
/// </summary>
private ScriptBlock OnGet
{
get;
set;
}
/// <summary>
/// The ScriptBlock that runs to get the value of the variable.
/// </summary>
private ScriptBlock OnSet
{
get;
set;
}
/// <summary>
/// Gets or sets the underlying value of the variable.
/// </summary>
public override object Value
{
get
{
if (OnGet == null) {
return null;
}
return OnGet.Invoke();
}
set
{
if (OnSet == null) {
throw new InvalidOperationException("The variable is read-only.");
}
OnSet.Invoke(value);
}
}
#endregion
}
}