PowerShellでC#のスクリプトを使ってVBAのEnum（定数）を表示する

```csharp:Ps_RunCSharpandOuOFiiceEnum.ps1
# Python風に、トップレベルであれば$moduleに"__main__"が入るようにしている。
# 他のPowershellプロセスを立ち上げるときには、$moduleに"called"を入れるようにする。
param([string]$module)
if($module -eq ""){ $module = "__main__"}
# コンパイル・実行を行う関数の定義
function ComplieAndRun(){

# CSharpコードのソース
$Source=@"
using System;
using System.Runtime.InteropServices;
using ComTypes = System.Runtime.InteropServices.ComTypes;

namespace ListTypeLibInfo
{
public class Program
{
[DllImport("oleaut32.dll", PreserveSig=false)]
public static extern ComTypes.ITypeLib LoadTypeLib([In, MarshalAs(UnmanagedType.LPWStr)] string typelib);

public static void Main(string[] args)
{
ComTypes.ITypeLib lib;
try {
lib = LoadTypeLib(@args[0]);
} catch (Exception ex) {
Console.WriteLine("Error:" + ex.Message);
//Console.ReadKey(true);
return;
}
for (int i = 0; i < lib.GetTypeInfoCount(); i++) {
IntPtr ppta;
ComTypes.ITypeInfo info;
int con;
string sname, doc, hlp;
lib.GetTypeInfo(i, out info);
info.GetDocumentation(-1, out sname, out doc, out con, out hlp);
info.GetTypeAttr(out ppta);
try {
ComTypes.TYPEATTR ta = (ComTypes.TYPEATTR)Marshal.PtrToStructure(ppta, typeof(ComTypes.TYPEATTR));
if (ta.typekind == ComTypes.TYPEKIND.TKIND_ENUM) {
for (int j = 0; j < ta.cVars; j++) {
IntPtr ppvd;
int pcnames;
string[] names = {string.Empty};
info.GetVarDesc(j, out ppvd);
try {
ComTypes.VARDESC vd = (ComTypes.VARDESC)Marshal.PtrToStructure(ppvd, typeof(ComTypes.VARDESC));
info.GetNames(vd.memid, names, 1, out pcnames);
Console.WriteLine("{0}\t{1}\t{2}", sname, names[0], Marshal.GetObjectForNativeVariant(vd.desc.lpvarValue));
} finally {
info.ReleaseVarDesc(ppvd);
}
}
}
} finally {
info.ReleaseTypeAttr(ppta);
}
}
//Console.Write("Press any key to continue . . . ");
//Console.ReadKey(true);
}
}
}

"@
# CSharpコードのコンパイル
Add-Type -Language CSharpVersion3 -TypeDefinition $Source

# CSharpコードの実行
Cls;
#[ListTypeLibInfo.Program]::main("C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA7.1\VBE7.DLL")
#[ListTypeLibInfo.Program]::main("C:\Program Files (x86)\Common Files\Microsoft Shared\OFFICE15\MSO.DLL")
#[ListTypeLibInfo.Program]::main("C:\Program Files (x86)\Common Files\Microsoft Shared\DAO\dao360.dll")
#[ListTypeLibInfo.Program]::main("C:\Program Files (x86)\Common Files\Microsoft Shared\OFFICE15\acedao.dll")
#[ListTypeLibInfo.Program]::main("C:\Windows\system32\stdole2.tlb")
#[ListTypeLibInfo.Program]::main("C:\Windows\SysWow64\stdole2.tlb")
#[ListTypeLibInfo.Program]::main("C:\DsoFile\dsofile.dll")
[ListTypeLibInfo.Program]::main("C:\Program Files (x86)\Microsoft Office\Office15\Excel.exe")
#X[ListTypeLibInfo.Program]::main("C:\Program Files (x86)\Common Files\Microsoft Shared\OFFICE15\acecore.dll")
#X[ListTypeLibInfo.Program]::main("C:\Program Files (x86)\Common Files\Microsoft Shared\OFFICE15\ACEOLEDB.DLL")
}
# トップレベルでない場合のみ、コンパイル・実行を行う。-
if($module -ne "__main__"){
ComplieAndRun
[Console]::ReadKey() | Out-Null # 実行後入力を待つ
}

# トップレベルの場合は、別のPowershellプロセスを立ち上げ、自身のスクリプトを呼び出す。
if($module -eq "__main__"){
$path = '"' + $Script:MyInvocation.MyCommand.Path + '"'
start-process powershell.exe -ArgumentList @('-File', $path, 'called')
}
<#
https://blogs.technet.microsoft.com/stefan_gossner/2010/05/07/using-csharp-c-code-in-powershell-scripts/
https://stackoverflow.com/questions/25619169/deploying-32-bit-access-system-to-64-bit-office-machine
#>
```
###参考文献
[PowerShellスクリプト内でC#コードを書いて使う](http://yomon.hatenablog.com/entry/2013/06/05/PowerShell%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E5%86%85%E3%81%A7C%23%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%84%E3%81%A6%E4%BD%BF%E3%81%86)
[TypeLibraryから列挙型の情報を取得するC#コード](https://www.ka-net.org/blog/?p=6828)
これがメインだが、画面のキャプチャからVBA7.dllをかませないと動かないことがわかる
[PowerShellからC#, SQL Serverのコードをとっても便利に呼び出す - threecourse's memo](http://threeprogramming.lolipop.jp/blog/?p=812)

###Typelib32が使えない
しかしC#は使えないと思っていましたが、Powershellに含められるんですね

###Add-Typeは一度使うとスクリプトが変更できない
しかしthreecourse'sによると使えるようになる。

###使い方
上記を何とかps１形式で保存
#[ListTypeLibInfo.Program]
このどれかを選んでシャープを消すと違う
#X[ListTypeLibInfo.Program]
とXがついているのものは表示できなかった。