1. kob58im

    Posted

    kob58im
Changes in title
+C#でPowerShellを使ってCOMオブジェクトのブラウザを作ってみた
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,248 @@
+
+
+```csharp
+using System;
+using System.Collections;
+using System.Collections.ObjectModel;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Windows.Forms;
+using System.Management.Automation;
+
+class MainForm:Form
+{
+ Button btn;
+ SplitContainer spl;
+ ListView lsvObj;
+ ListView lsvMemb;
+ ListView lsvMethod;
+
+ static Collection<PSObject> GetObjNames()
+ {
+ string[] source = new string[] {
+ @"$a = dir REGISTRY::HKEY_CLASSES_ROOT\CLSID -Include PROGID -Recurse",
+ "$a | foreach {$_.GetValue(\"\")} | sort"
+ };
+
+ using ( var invoker = new RunspaceInvoke() ) {
+ Collection<PSObject> tmp = invoker.Invoke(source[0]);
+ Collection<PSObject> result = invoker.Invoke(source[1]);
+ return result;
+ }
+ }
+
+
+
+ MainForm()
+ {
+ Text = "Object Browser";
+
+ btn = new Button();
+ btn.Size = new System.Drawing.Size(130,25);
+ btn.Text = "Get Object List";
+ btn.Click += (sender,e)=>{ReloadPSObject();};
+ Controls.Add(btn);
+
+ spl = new SplitContainer();
+ spl.Location = new Point(0, btn.Bottom);
+ spl.Orientation = Orientation.Vertical;
+ Controls.Add(spl);
+
+ ////// 左 Panel ここから
+ lsvObj = new ListView();
+ lsvObj.View = View.Details;
+ lsvObj.FullRowSelect =true;
+ lsvObj.GridLines = true;
+ lsvObj.Columns.Add("Name", 170, HorizontalAlignment.Left);
+ lsvObj.Dock = DockStyle.Fill;
+ lsvObj.SelectedIndexChanged += LsvObj_SelectedIndexChanged;
+ spl.Panel1.Controls.Add(lsvObj);
+ ////// 左 Panel ここまで
+
+ ////// 右 Panel ここから
+ var tabc = new TabControl();
+ tabc.Dock = DockStyle.Fill;
+ spl.Panel2.Controls.Add(tabc);
+
+ var tabp1 = new TabPage();
+ tabp1.Text = "Members";
+ tabp1.Dock = DockStyle.Fill;
+ tabc.Controls.Add(tabp1);
+
+ lsvMemb = new ListView();
+ lsvMemb.View = View.Details;
+ lsvMemb.FullRowSelect =true;
+ lsvMemb.GridLines = true;
+ lsvMemb.Columns.Add("Name", 90, HorizontalAlignment.Left);
+ lsvMemb.Columns.Add("MemberType", 90, HorizontalAlignment.Left);
+ lsvMemb.Columns.Add("TypeNameOfValue", 230, HorizontalAlignment.Left);
+ lsvMemb.Dock = DockStyle.Fill;
+ tabp1.Controls.Add(lsvMemb);
+
+ // --
+
+ var tabp2 = new TabPage();
+ tabp2.Text = "Methods";
+ tabp2.Dock = DockStyle.Fill;
+ tabc.Controls.Add(tabp2);
+
+ lsvMethod = new ListView();
+ lsvMethod.View = View.Details;
+ lsvMethod.FullRowSelect =true;
+ lsvMethod.GridLines = true;
+ lsvMethod.Columns.Add("ReturnType", 90, HorizontalAlignment.Left);
+ lsvMethod.Columns.Add("Name", 90, HorizontalAlignment.Left);
+ lsvMethod.Columns.Add("Arguments", 300, HorizontalAlignment.Left);
+ lsvMethod.Dock = DockStyle.Fill;
+ tabp2.Controls.Add(lsvMethod);
+ ////// 右 Panel ここまで
+
+ ClientSize = new System.Drawing.Size(700,530);
+
+
+ Load += Form_Resize;
+ Resize += Form_Resize;
+ ResizeEnd += Form_Resize;
+ }
+
+ void Form_Resize(object sender, EventArgs e)
+ {
+ spl.Size = new System.Drawing.Size(ClientSize.Width, ClientSize.Height - spl.Top);
+ }
+
+ void ReloadPSObject()
+ {
+ Collection<PSObject> psObjs;
+
+ btn.Enabled = false; // 処理に時間がかかるので操作を禁止しておく。※結局押したら意味ないかも
+ try {
+ psObjs = GetObjNames();
+ }
+ finally {
+ btn.Enabled = true;
+ }
+
+ lsvObj.Items.Clear();
+ lsvObj.BeginUpdate();
+ try {
+ foreach ( var t in psObjs ) {
+ lsvObj.Items.Add(MyNewListItem_LsvObj(t));
+ }
+ }
+ finally {
+ lsvObj.EndUpdate();
+ }
+ }
+
+ void ReloadPSMemberInfo(PSMemberInfoCollection<PSMemberInfo> memberInfos)
+ {
+ lsvMemb.Items.Clear();
+ lsvMemb.BeginUpdate();
+ try {
+ foreach ( var mi in memberInfos ) {
+ lsvMemb.Items.Add(MyNewListItem_LsvMemb(mi));
+ }
+ }
+ finally {
+ lsvMemb.EndUpdate();
+ }
+ }
+
+ void ReloadPSMethodInfo(PSMemberInfoCollection<PSMethodInfo> methodInfos)
+ {
+ lsvMethod.Items.Clear();
+ lsvMethod.BeginUpdate();
+ try {
+ foreach ( var mi in methodInfos ) {
+ foreach ( string s in mi.OverloadDefinitions ) {
+ lsvMethod.Items.Add(MyNewListItem_LsvMethod(s));
+ }
+ }
+ }
+ finally {
+ lsvMethod.EndUpdate();
+ }
+ }
+
+ ListViewItem MyNewListItem_LsvObj(PSObject psObj)
+ {
+ var itm = new ListViewItem(new string[]{psObj.ToString()});
+ itm.Tag = psObj;
+ return itm;
+ }
+
+ ListViewItem MyNewListItem_LsvMemb(PSMemberInfo mi)
+ {
+ // https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.psmemberinfocollection-1.item?view=pscore-6.2.0
+ var itm = new ListViewItem(new string[]{mi.Name, mi.MemberType.ToString(), mi.TypeNameOfValue});
+ return itm;
+ }
+
+ ListViewItem MyNewListItem_LsvMethod(string s)
+ {
+ ListViewItem itm;
+ Regex r = new Regex(@"^([^ ]+) ([^( ]+)\((.*)\)$");
+ Match m = r.Match(s);
+
+ if ( m.Success ) {
+ string returnType = m.Groups[1].Value;
+ string methodName = m.Groups[2].Value;
+ string arguments = m.Groups[3].Value;
+ itm = new ListViewItem(new string[]{returnType , methodName, arguments});
+ }
+ else {
+ // 想定外の形式の場合は、とりあえず全文表示しておく
+ itm = new ListViewItem(new string[]{"", "", s});
+ }
+ return itm;
+ }
+
+
+ void LsvObj_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (lsvObj.SelectedIndices.Count != 1) {return;}
+
+ int index = lsvObj.SelectedIndices[0];
+ PSObject psObj = (PSObject)(lsvObj.Items[index].Tag);
+
+ ReloadPSMemberInfo(psObj.Members);
+ ReloadPSMethodInfo(psObj.Methods);
+ }
+
+
+
+ [STAThread]
+ static void Main(){
+ Application.Run(new MainForm());
+ }
+}
+
+機能追加したいこと:
+・検索(filtering)
+・テキストコピーできるようにする
+・オブジェクトリストの取得に時間かかるのでキャッシュしたい・・
+
+```
+
+# コンパイル方法
+
+```
+csc ^
+/r:C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll ^
+xxxx.c
+```
+
+# 参考サイト
+- [powershellのよびだし (++C++)](https://ufcpp.net/study/powershell/interop.html)
+
+- [PSObjectクラス (Microsoft) ](https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.psobject?view=pscore-6.2.0)