Shell.Application动词.Net 3.5

时间:2017-03-15 20:23:04

标签: c#

我正在尝试在.net 3.5中编写以下代码。代码试图循环动词(即Pin to Start,Open,Create Shortcut等)

此代码在4.5

中执行此操作
    string path = Path.GetDirectoryName(filePath);
    string fileName = Path.GetFileName(filePath);

    // create the shell application object
    dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
    dynamic directory = shellApplication.NameSpace(path);
    dynamic link = directory.ParseName(fileName);
    dynamic verbs = link.Verbs();



    for (int i = 0; i < verbs.Count(); i++)
    {
        dynamic verb = verbs.Item(i);
        var name = verb.Name;
        if (verb.Name.Equals(localizedVerb))
        {
            verb.DoIt();
            return true;
        }
    }

我试图在3.5中将此代码翻译为

        Shell shellApplication = new ShellClass();
        string path = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);
        Folder directory = GetShell32NameSpaceFolder(path);
        FolderItem link = directory.ParseName(fileName);
        FolderItemVerbs verbs = link.Verbs();

        for (var i = 0; i < verbs.Count; i++)
        {
            FolderItemVerb verb = verbs.Item(i);

            logger.WriteDebug("Verb Search: " + verb.Name);
            if (verb.Name.Equals(localizedVerb))
            {
                logger.WriteDebug("Verb Found: " + verb.Name);
                verb.DoIt();
                return true;
            }
        }

这很有用..它找到了动词,但由于某种原因,不是动词后面的&#34; Pin to Start&#34;。

如何将上面的4.5代码翻译成3.5,以便找到win10(或至少是win7)操作系统的所有动词?

1 个答案:

答案 0 :(得分:2)

其实你已经有了答案! 问题是Windows中的动词是根据文件类型配置的。你还没有指定你要查找的文件类型,所以我已经在我的机器上运行你的代码来对抗一些常见的类型,从快捷方式开始,这是显而易见的一个

  

(。lnk)C:\ ProgramData \ Microsoft \ Windows \ Start Menu \ Programs \ Outlook 2016.lnk

Verb Search: &Open
Verb Search: Open file locat&ion
Verb Search: Run as &administrator
Verb Search: Troubleshoot compatibilit&y
Verb Search: &Pin to Start
Verb Search: Scan with Windows Defender...
Verb Search: Restore previous &versions
Verb Search: 
Verb Search: Cu&t
Verb Search: &Copy
Verb Search: Create &shortcut
Verb Search: &Delete
Verb Search: Rena&me
Verb Search: P&roperties

现在如果我为文本文件运行相同的内容:

  

(。txt)\\ PDC \ Folder Redirection \ chris \ Documents \ who knows.txt

Verb Search: &Open
Verb Search: &Print
Verb Search: &Edit
Verb Search: Scan with Windows Defender...
Verb Search: 
Verb Search: Restore previous &versions
Verb Search: 
Verb Search: Cu&t
Verb Search: &Copy
Verb Search: Create &shortcut
Verb Search: &Delete
Verb Search: Rena&me
Verb Search: P&roperties

现在,如果我为文件夹运行相同的内容:

  

(目录)\\ PDC \文件夹重定向\ chris \ Documents

Verb Search: &Open
Verb Search: Pin to Quick access
Verb Search: Open in &Visual Studio
Verb Search: Scan with Windows Defender...
Verb Search: Restore previous &versions
Verb Search: &Pin to Start
Verb Search: 
Verb Search: Cu&t
Verb Search: &Copy
Verb Search: Create &shortcut
Verb Search: &Delete
Verb Search: Rena&me
Verb Search: P&roperties

那么这些难以捉摸的动词在哪里配置?在注册表中。见:

MSDN: Verbs and File Associations

Registering Verbs for File Name Extensions

  

注意:如果你想要固定一个不支持固定的文件,那么就不要简单地创建一个SHORTCUT到那个文件......我刚刚尝试过,windows仍然会显示快捷方式目标的动词!但这是有道理的,因为使用Windows跳转列表,我们通常将用于打开项目的程序固定,然后我们可以将项目固定在该程序的跳转列表中。

为了好玩,我添加了我的代码探索,试图创建快捷方式,以防其他人找到它的用途。我还更改了日志语句,以便从具有有限引用的控制台应用程序运行。

using Shell32; // Add COM reference to Microsoft Shell controls and Automation

static class Program
{
    public const string PIN_TO_START = "&Pin to Start";
    public const string CREATE_SHORTCUT = "Create &shortcut";
    [STAThread]
    static void Main()
    {
        // Test with a text file, text files do not have "Pin to Start" as a standard verb
        string path = @"\\PDC\Folder Redirection\chris\Documents\who knows.txt";
        string localizedVerb = "&Pin to Start";

        if (ExecuteShellVerb(path, localizedVerb))
            Debug.WriteLine($"Verb '{localizedVerb}' executed on {path}");
        else if (localizedVerb.Equals(PIN_TO_START))
        {
            // Create a shortcut to the item, by cheating with the Create Shortcut verb :)
            // You could do this a number of ways, this is just one idea to point you in the right direction
            if (ExecuteShellVerb(path, CREATE_SHORTCUT))
            {
                // by default the shortcut name will be the same as the item, but with a ' - Shortcut.lnk' appended
                // You know how windows naming conventions work and what the possibilities are here :)
                string shortcutPath = $"{path} - Shortcut.lnk";
                Debug.WriteLine($"Created Shortcut: {shortcutPath}");
                if (ExecuteShellVerb(shortcutPath, localizedVerb))
                    Debug.WriteLine($"Verb '{localizedVerb}' executed on {shortcutPath}");
                else
                    Debug.WriteLine($"Failed to execute verb '{localizedVerb}' on the created shortcut: {shortcutPath}");
            }
            else
            {
                Debug.WriteLine($"Failed to create Shortcut using verb.");
                // TODO: create the shortcut manually
            }
        }
    }

    private static bool ExecuteShellVerb(string filePath, string localizedVerb)
    {
        Shell shellApplication = new ShellClass();

        string path = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);
        Folder directory = GetShell32NameSpaceFolder(path);
        FolderItem link = directory.ParseName(fileName);
        FolderItemVerbs verbs = link.Verbs();

        for (var i = 0; i < verbs.Count; i++)
        {
            FolderItemVerb verb = verbs.Item(i);

            Debug.WriteLine("Verb Search: " + verb.Name);
            if (verb.Name.Equals(localizedVerb))
            {
                Debug.WriteLine("Verb Found: " + verb.Name);
                verb.DoIt();
                return true;
            }
        }
        return false;
    }

    public static Shell32.Folder GetShell32NameSpaceFolder(Object folder)
    {
        Type shellAppType = Type.GetTypeFromProgID("Shell.Application");

        Object shell = Activator.CreateInstance(shellAppType);
        return (Shell32.Folder)shellAppType.InvokeMember("NameSpace",
        System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { folder });
    }

}

此执行的输出:

Verb Search: &Open
Verb Search: &Print
Verb Search: &Edit
Verb Search: Scan with Windows Defender...
Verb Search: 
Verb Search: Restore previous &versions
Verb Search: 
Verb Search: Cu&t
Verb Search: &Copy
Verb Search: Create &shortcut
Verb Search: &Delete
Verb Search: Rena&me
Verb Search: P&roperties
Verb Search: &Open
Verb Search: &Print
Verb Search: &Edit
Verb Search: Scan with Windows Defender...
Verb Search: 
Verb Search: Restore previous &versions
Verb Search: 
Verb Search: Cu&t
Verb Search: &Copy
Verb Search: Create &shortcut
Verb Found: Create &shortcut
Created Shortcut: \\PDC\Folder Redirection\chris\Documents\who knows.txt - Shortcut.lnk
Verb Search: &Open
Verb Search: Open file locat&ion
Verb Search: &Print
Verb Search: &Edit
Verb Search: Scan with Windows Defender...
Verb Search: 
Verb Search: Restore previous &versions
Verb Search: 
Verb Search: Cu&t
Verb Search: &Copy
Verb Search: Create &shortcut
Verb Search: &Delete
Verb Search: Rena&me
Verb Search: P&roperties
Failed to execute verb '&Pin to Start' on the created shortcut: \\PDC\Folder Redirection\chris\Documents\who knows.txt - Shortcut.lnk