2017-04-10 76 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以來支持的「嵌入互操作類型」功能消除了任何可以避免的理由。

項目>添加引用> COM選項卡。勾選「Microsoft Internet Controls」和「Microsoft Shell Controls and Automation」。現在,你可以把它寫早期綁定,美觀大方,結構緊湊,智能感知的所有好處,以幫助您找到正確的成員,並避免錯別字:

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(); 
} 

稍微傻例子,它刷新誰的顯示的路徑是任何資源管理器窗口位於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