从 C# 创建 PowerShell 自动变量
我试图使自动变量可用于 Excel VBA(如 ActiveSheet 或 ActiveCell),也可用于 PowerShell 作为“自动变量”。 PowerShell 引擎托管在 Excel VSTO 加载项中,Excel.Application 可作为 Globals.ThisAddin.Application 使用。我在 StackOverflow 上找到了这个线程并开始创建PSVariable 派生类如:
public class ActiveCell : PSVariable
{
public ActiveCell(string name) : base(name) { }
public override object Value
{
get
{
return Globals.ThisAddIn.Application.ActiveCell;
}
}
}
public class ActiveSheet : PSVariable
{
public ActiveSheet(string name) : base(name) { }
public override object Value
{
get
{
return Globals.ThisAddIn.Application.ActiveSheet;
}
}
}
并将它们的实例添加到当前 POwerShell 会话:
runspace.SessionStateProxy.PSVariable.Set(new ActiveCell("ActiveCell"));
runspace.SessionStateProxy.PSVariable.Set(new ActiveSheet("ActiveSheet"));
这有效,我可以将 PowerShell 中的这些变量用作 $ActiveCell 和 $ActiveSheet (它们的值随着 Excel 活动工作表或单元格的更改而变化)。然后我阅读了 PSVariable 文档 这里< /a> 并看到:
“没有从此类派生的既定方案。要以编程方式创建 shell 变量,请创建此类的实例并使用 PSVariableIntrinsics 类对其进行设置。”
当我从 PSVariable 派生时,我尝试使用建议的内容:
PSVariable activeCell = new PSVariable("ActiveCell");
activeCell.Value = Globals.ThisAddIn.Application.ActiveCell;
runspace.SessionStateProxy.PSVariable.Set(activeCell);
使用此功能,$ActiveCell 出现在我的 PowerShell 会话中,但当我更改 Excel 中的活动单元格时,其值不会更改。
PSVariable 文档中的上述注释是我应该担心的吗,或者我可以继续创建 PSVariable 派生类吗?是否有另一种方法可以使 Excel 全局变量可用于 PowerShell?
I trying to make automatic variables available to Excel VBA (like ActiveSheet or ActiveCell) also available to PowerShell as 'automatic variables'. PowerShell engine is hosted in an Excel VSTO add-in and Excel.Application is available to it as Globals.ThisAddin.Application. I found this thread here on StackOverflow and started created PSVariable derived classes like:
public class ActiveCell : PSVariable
{
public ActiveCell(string name) : base(name) { }
public override object Value
{
get
{
return Globals.ThisAddIn.Application.ActiveCell;
}
}
}
public class ActiveSheet : PSVariable
{
public ActiveSheet(string name) : base(name) { }
public override object Value
{
get
{
return Globals.ThisAddIn.Application.ActiveSheet;
}
}
}
and adding their instances to the current POwerShell session:
runspace.SessionStateProxy.PSVariable.Set(new ActiveCell("ActiveCell"));
runspace.SessionStateProxy.PSVariable.Set(new ActiveSheet("ActiveSheet"));
This works and I am able to use those variables from PowerShell as $ActiveCell and $ActiveSheet (their value change as Excel active sheet or cell change). Then I read PSVariable documentation here and saw this:
"There is no established scenario for deriving from this class. To programmatically create a shell variable, create an instance of this class and set it by using the PSVariableIntrinsics class."
As I was deriving from PSVariable, I tried to use what was suggested:
PSVariable activeCell = new PSVariable("ActiveCell");
activeCell.Value = Globals.ThisAddIn.Application.ActiveCell;
runspace.SessionStateProxy.PSVariable.Set(activeCell);
Using this, $ActiveCell appears in my PowerShell session, but its value doesn't change as I change the active cell in Excel.
Is the above comment from PSVariable documentation something I should worry about, or I can continue creating PSVariable derived classes? Is there another way of making Excel globals available to PowerShell?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我们的文档是错误的 - 这是受支持的场景。
以下是有关该技术的更多信息:
李·霍姆斯 [MSFT]
Windows PowerShell 开发
Our documentation is wrong - it is a supported scenario.
Here's a bit more about the technique:
Lee Holmes [MSFT]
Windows PowerShell Development
显然,在第二个示例中,您不是从 PSVariable 派生的,您不能期望 $ActiveCell 变量随 ActiveCell 属性的值而变化,因为您只捕获其值一次。
我不认为从 PSVariable 派生是受支持的方案,但它确实有效,而且我已经通过添加
$Now
和$Today
等变量来实现。只向 PowerShell 脚本公开 $Application 变量而不是 Application 对象的各种属性可能是一个更好的主意。这样做的好处是,您不需要创建一堆自动变量,并且 PowerShell 脚本可以使用 $Application.ActiveCell 访问 Application 对象必须提供的任何内容。另一个好处是它根本不需要是自动变量,因为应用程序对象引用永远不会改变。
说了这么多,我已经包含了一个我时常使用的 PSVariable 子类,它采用 ScriptBlock 作为 getter 和 setter。这让我可以从 PowerShell 定义自动变量,而无需为每个变量创建单独的派生类。
Obviously in your second example, where you are not deriving from PSVariable, you couldn't expect the $ActiveCell variable to change with the value of the ActiveCell property since you're capturing its value just once.
I don't believe deriving from PSVariable is a supported scenario, but it does work and I've done it to add variables such as
$Now
and$Today
.It might be a better idea to just expose an $Application variable to PowerShell script instead of the various properties of the Application object. The upside to this is that you wouldn't need to create a bunch of automatic variables and PowerShell scripts could access anything the Application object has to offer by using $Application.ActiveCell. The other benefit is that it doesn't need to be an automatic variable at all because the Application object reference will never change.
Having said all that, I've included a subclass of PSVariable that I use from time to time which takes a ScriptBlock for the getter and setter. This lets me define automatic variables from PowerShell without needing a separate derived class for each one.