Ich teste PowerShell-Hosting mit C#. Hier ist eine Konsolenanwendung, die funktioniert:Übergeben einer Variablen aus dem benutzerdefinierten Aufgabenbereich von Excel 2007 an Hosted 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);
}
}
}
}
ich zum ersten Mal eine Excel.Application Instanz erstellen und an die gehostete Powershell-Instanz als varible namens $ Anwendung übergeben. Das funktioniert und ich kann diese Variable verwenden, als ob Excel.Application von PowerShell aus erstellt wurde.
Ich erstellte als nächstes ein Excel-Add-In mit VS 2008 und fügte ein Benutzersteuerelement mit zwei Textfeldern und einer Schaltfläche zum Add-In hinzu (das Benutzersteuerelement wird als benutzerdefinierter Aufgabenbereich angezeigt, wenn Excel gestartet wird). Die Idee war folgende: Wenn ich auf die Schaltfläche klicke, wird eine gehostete PowerShell-Instanz erstellt und ich kann die aktuelle Excel.Application -Instanz wie im ersten Beispiel als Variable übergeben, sodass ich diese Variable verwenden kann, um Excel aus PowerShell zu automatisieren (ein Textfeld würde für die Eingabe und die andere für die Ausgabe verwendet werden, hier der Code.
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;
}
}
}
}
der Code ist ähnlich zu der ersten Probe, mit der Ausnahme, dass die aktuelle Excel.Application Instanz an die addin verfügbar über Globals.ThisAddIn.Application (VSTO generiert) und ich kann sehen, dass es wirklich eine Microsoft.Office.Interop.Excel.Application-Instanz ist, weil ich Dinge wie app.ActiveCell.Value2 = "Test" (das tatsächlich den Text setzt in die aktive Zelle), aber wenn ich die Excel.Application-Instanz an die PowerShell-Instanz überlasse, was g Es gibt eine Instanz von System .__ ComObject und ich kann nicht herausfinden, wie es in Excel.Application umgewandelt wird. Wenn ich die Variable von PowerShell mit $ Application | untersuche Get-Member Dies ist die Ausgabe I im zweiten Textfeld erhalten:
TypeName: System.__ComObject Name MemberType Definition ---- ---------- ---------- CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObj... Equals Method System.Boolean Equals(Object obj) GetHashCode Method System.Int32 GetHashCode() GetLifetimeService Method System.Object GetLifetimeService() GetType Method System.Type GetType() InitializeLifetimeService Method System.Object InitializeLifetimeService() ToString Method System.String ToString()
Meine Frage ist, wie kann ich eine Instanz von Microsoft.Office.Interop.Excel.Application gehen von einem VSTO Excel 2007 AddIn erzeugt ein gehostet PowerShell-Instanz, so kann ich es von PowerShell manipulieren?
(ich habe geschrieben zuvor die Frage in der Microsoft C# Forum ohne Antwort)
Vielen Dank für die Antwort. InvokeMember funktioniert sicherlich, zum Beispiel: Pipeline pipeline = runspace.CreatePipeline ("[System .__ ComObject] .InvokeMember (\" Version \ ", [System.Reflection.BindingFlags] :: GetProperty, $ null, $ Application, $ null) | Out-String "); return '12 .0 'Aber wenn es keine Möglichkeit gibt, $ Application in Excel.Application zu casten, kompliziert dies die Dinge. Die Idee war, Excel.Application vom Add-In an PowerShell zu übergeben und einfach so zu verwenden, als wäre es in PowerShell erstellt worden. –