简体   繁体   English

InvokeMember获得特定属性值的可能值

[英]Possible values for InvokeMember to get specific property value

I'm referring this thread to refresh the windows explorer, I want to refresh some windows only, which means I want to filter the opened windows according to their title or path. 我指的是此线程来刷新Windows资源管理器,我只想刷新一些窗口,这意味着我想根据打开的窗口的标题或路径来过滤它们。 Let me copy the code from that thread for more clarification: 让我从该线程复制代码以进一步说明:

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

What I understood from the above code is: By using this line windowsType.InvokeMember("Item", System.Reflection.BindingFlags.InvokeMethod, null, windows, new object[] { i }); 从上面的代码中我了解到的是:通过使用以下行windowsType.InvokeMember("Item", System.Reflection.BindingFlags.InvokeMethod, null, windows, new object[] { i }); we will get the current window object, and then we are using .InvokeMember("Name".. to get the name of that object, like wise what should I pass to InvokeMember method to get the path of that object or the title of that window? or can anyone tell me the possible alternative values for "Name" in the above statement? 我们将获取当前的窗口对象,然后使用.InvokeMember("Name"..来获取该对象的名称,就像明智的做法是,我应该将什么传递给InvokeMember方法以获取该对象的路径或该对象的标题窗口?还是有人可以告诉我上述声明中"Name"的可能替代值?

What I'm expecting is some code like the following: 我期望的是一些类似以下的代码:

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

I can give you more information if you need, expecting expert's suggestion to solve this issue, 如有需要,我可以为您提供更多信息,期待专家的建议来解决此问题,

Thanks in advance 提前致谢

This is the way you had to write late-bound COM client code in the Bad Old Days. 这是您在Bad Old Days中必须编写后期绑定的COM客户端代码的方式。 Considerable pain and suffering to get it going, what is in the snippet is not close yet. 要使它进展下去,会带来相当大的痛苦和磨难,摘要中的内容还没有结束。 I'll first propose a very different way to do this, there just isn't any point in doing it late-bound since these COM objects are available on any Windows version and are never going to change anymore. 首先,我将提出一种非常不同的方法来进行此操作,因为这些COM对象在任何Windows版本上都可用,并且以后将不再更改,因此后期绑定没有任何意义。 The "Embed Interop Types" feature supported since VS2010 removes any good reason to avoid it. 自VS2010以来,受支持的“嵌入互操作类型”功能消除了避免它的任何充分理由。

Project > Add Reference > COM tab. 项目>添加引用>“ COM”选项卡。 Tick "Microsoft Internet Controls" and "Microsoft Shell Controls and Automation". 勾选“ Microsoft Internet控件”和“ Microsoft Shell控件和自动化”。 Now you can write it early-bound, nice and compact with all the benefits of IntelliSense to help you find the correct members and avoid typos: 现在,您可以使用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 slightly silly example, it refreshes any Explorer window who's displayed path is located on the C drive. 一个稍微愚蠢的示例,它刷新了显示路径位于C驱动器上的任何“资源管理器”窗口。 Note how the Path property is not useful to discover what is displayed, LocationURL is needed. 请注意,Path属性对发现所显示内容无用,需要LocationURL。 You might have to find the distinction between Internet Explorer and Windows Explorer windows (aka "File Explorer"), albeit that IE can also display directory content so I think this is the most correct version. 您可能必须找到Internet Explorer和Windows Explorer窗口(也称为“文件资源管理器”)之间的区别,尽管IE也可以显示目录内容,所以我认为这是最正确的版本。

If you really want to do this late-bound then use the dynamic keyword to minimize the suffering. 如果您确实想在后期进行此操作,请使用dynamic关键字将痛苦降到最低。 In this case almost identical: 在这种情况下几乎相同:

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

Answering your question explicitly, use "LocationURL". 明确回答您的问题,请使用“ LocationURL”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM