C# を使用して PowerShell ホスティングをテストしています。動作するコンソール アプリケーションを次に示します。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using Microsoft.Office.Interop.Excel;
namespace ConsoleApplication3
{
class Program
{
static void Main()
{
Application app = new Application();
app.Visible = true;
app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
runspace.SessionStateProxy.SetVariable("Application", app);
Pipeline pipeline = runspace.CreatePipeline("$Application");
Collection<PSObject> results = null;
try
{
results = pipeline.Invoke();
foreach (PSObject pob in results)
{
Console.WriteLine(pob);
}
}
catch (RuntimeException re)
{
Console.WriteLine(re.GetType().Name);
Console.WriteLine(re.Message);
}
}
}
}
最初に Excel.Application インスタンスを作成し、ホストされている PowerShell インスタンスに $Application という名前の変数として渡します。これは機能し、Excel.Application が PowerShell 内から作成されたかのように、この変数を使用できます。
次に、VS 2008 を使用して Excel アドインを作成し、2 つのテキスト ボックスと 1 つのボタンを含むユーザー コントロールをアドインに追加しました (ユーザー コントロールは、Excel の起動時にカスタム作業ウィンドウとして表示されます)。ボタンをクリックすると、ホストされた PowerShell インスタンスが作成され、最初のサンプルと同様に、現在の Excel.Application インスタンスを変数として渡すことができるため、この変数を使用して PowerShell から Excel を自動化できます。 (1 つのテキスト ボックスは入力に使用され、もう 1 つは出力に使用されます。コードは次のとおりです。
using System;
using System.Windows.Forms;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using Microsoft.Office.Interop.Excel;
namespace POSHAddin
{
public partial class POSHControl : UserControl
{
public POSHControl()
{
InitializeComponent();
}
private void btnRun_Click(object sender, EventArgs e)
{
txtOutput.Clear();
Microsoft.Office.Interop.Excel.Application app =
Globals.ThisAddIn.Application;
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
runspace.SessionStateProxy.SetVariable("Application", app);
Pipeline pipeline = runspace.CreatePipeline(
"$Application | Get-Member | Out-String");
app.ActiveCell.Value2 = "Test";
Collection<PSObject> results = null;
try
{
results = pipeline.Invoke();
foreach (PSObject pob in results)
{
txtOutput.Text += pob.ToString() + "-";
}
}
catch (RuntimeException re)
{
txtOutput.Text += re.GetType().Name;
txtOutput.Text += re.Message;
}
}
}
}
コードは最初のサンプルと似ていますが、現在の Excel.Application インスタンスが Globals.ThisAddIn.Application (VSTO 生成) を介してアドインで使用可能であり、実際には Microsoft.Office.Interop.Excel.Application であることがわかります。 app.ActiveCell.Value2 = "Test" などを使用できるためです (これにより、実際にテキストがアクティブ セルに配置されます)。しかし、Excel.Application インスタンスを PowerShell インスタンスに渡すと、System.__ComObject のインスタンスが生成され、それを Excel.Application にキャストする方法がわかりません。$Application | を使用して PowerShell から変数を調べると、Get-Member これは、2 番目のテキスト ボックスに表示される出力です。
TypeName: System.__ComObject 名前 MemberType 定義 ---- ---------- ---------- CreateObjRef メソッド System.Runtime.Remoting.ObjRef CreateObj... Equals メソッド System.Boolean Equals(Object obj) GetHashCode メソッド System.Int32 GetHashCode() GetLifetimeService メソッド System.Object GetLifetimeService() GetType メソッド System.Type GetType() InitializeLifetimeService メソッド System.Object InitializeLifetimeService() ToString メソッド System.String ToString()
私の質問は、Microsoft.Office.Interop.Excel.Application のインスタンスを、VSTO で生成された Excel 2007 アドインから、ホストされている PowerShell インスタンスに渡し、PowerShell から操作できるようにする方法です。
(私は以前、回答なしで Microsoft C# フォーラムに質問を投稿しました)