2017-04-10 47 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