1. kob58im

    No comment

    kob58im
Changes in title
-C#でPowerShellを使ってCOMオブジェクトのブラウザを作ってみた
+C#でPowerShellを使ってCOMオブジェクトブラウザを作ってみた
Changes in tags
Changes in body
Source | HTML | Preview
@@ -1,248 +1,248 @@
+判ったこと:PSObjectのMembersプロパティやMethodsプロパティは、COMオブジェクトの情報は拾えないようである。。
```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)