2017-04-10 17 views
1

this thread私はWindowsエクスプローラをリフレッシュすると言っています。いくつかのウィンドウのみをリフレッシュしたいので、開いたウィンドウをタイトルまたはパスに従ってフィルタリングします。私はより明確にするため、そのスレッドからコードをコピーしてみましょう:InvokeMemberが特定のプロパティ値を取得するための可能な値

Guid CLSID_ShellApplication = new Guid("13709620-C279-11CE-A49E-444553540000"); 
Type shellApplicationType = Type.GetTypeFromCLSID(CLSID_ShellApplication, true); 

object shellApplication = Activator.CreateInstance(shellApplicationType); 
object windows = shellApplicationType.InvokeMember("Windows", System.Reflection.BindingFlags.InvokeMethod, null, shellApplication, new object[] { }); 

Type windowsType = windows.GetType(); 
object count = windowsType.InvokeMember("Count", System.Reflection.BindingFlags.GetProperty, null, windows, null); 
for (int i = 0; i < (int)count; i++) 
{ 
    object item = windowsType.InvokeMember("Item", System.Reflection.BindingFlags.InvokeMethod, null, windows, new object[] { i }); 
    Type itemType = item.GetType(); 

    string itemName = (string)itemType.InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null, item, null); 
    if (itemName == "Windows Explorer") 
    { 
     // Here I want to check whether this window need to be refreshed 
     // based on the opened path in that window 
     // or with the title of that window 
     // How do I check that here 
     itemType.InvokeMember("Refresh", System.Reflection.BindingFlags.InvokeMethod, null, item, null); 
    } 
} 

私は上記のコードから理解することです:私たちは現在のウィンドウオブジェクトを取得しますwindowsType.InvokeMember("Item", System.Reflection.BindingFlags.InvokeMethod, null, windows, new object[] { i });このラインを使用して、我々が取得する.InvokeMember("Name"..を使用していることでそのオブジェクトの名前、そのオブジェクトのパスまたはそのウィンドウのタイトルを取得するには、InvokeMemberメソッドに渡すべき賢明なように?または誰でも私に上記の文の"Name"の可能な代替値を教えてもらえますか?

私は何を期待してることは、次のようないくつかのコードです:

string itemPath = (string)itemType.InvokeMember("Something here", System.Reflection.BindingFlags.GetProperty, null, item, null); 

OR

string itemTitle = (string)itemType.InvokeMember("Something here", System.Reflection.BindingFlags.GetProperty, null, item, null); 

私はこの問題を解決するために、専門家の提案を期待して、あなたが必要な場合は、より多くの情報を与えることができ、

ありがとうございます。

答えて

2

これは、レイトバインドされたCOM悪い昔のクライアントコードかなりの痛みと苦しみがそれを得るためには、スニペットにあるものはまだ近くにありません。これらのCOMオブジェクトはどのWindowsバージョンでも利用可能であり、今後も変更されることは決してないため、これを行うには全く別の方法を提案します。 VS2010は、それを回避するための正当な理由を取り除いて以来、 "Interop Interp Types"機能がサポートされています。

プロジェクト>参照の追加> COMタブ。 「Microsoftインターネットコントロール」と「Microsoftシェルコントロールとオートメーション」をチェックします。今、あなたはあなたが正しいのメンバーを見つけて、タイプミスを避けるために、早期の結合のIntelliSenseのすべての利点といいとコンパクトなそれを書くことができます。

var shl = new Shell32.Shell(); 
foreach (SHDocVw.InternetExplorer win in shl.Windows()) { 
    var path = win.LocationURL; 
    if (!path.StartsWith("file:///")) continue; 
    path = System.IO.Path.GetFullPath(path.Substring(8)); 
    if (path.StartsWith("C")) win.Refresh(); 
} 

A少し愚かな例として、それはパスが表示されます任意のエクスプローラウィンドウを更新しますCドライブにあります。 Pathプロパティは、LocationURLが表示されているものを発見するのにどのように役立たないかに注意してください。 Internet ExplorerとWindowsエクスプローラのウィンドウ(別名「ファイルエクスプローラ」)を区別する必要があるかもしれませんが、IEがディレクトリコンテンツを表示できるので、これが最も正しいバージョンだと思います。

この遅延バインドを実際に実行する場合は、苦労を最小限に抑えるためにキーワードdynamicを使用してください。この場合はほぼ同じです:

dynamic shl = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); 
foreach (var win in shl.Windows()) { 
    string path = win.LocationURL; 
    if (!path.StartsWith("file:///")) continue; 
    path = System.IO.Path.GetFullPath(path.Substring(8)); 
    if (path.StartsWith("C")) win.Refresh(); 
} 

明示的に質問に答えるには、「LocationURL」を使用してください。

+0

ありがとうございます、私はupvote一度私は15 – Learning

関連する問題