0

语境

由于工作机器上的安全策略,我无法固定网络驱动器上的应用程序。但是,我找到了一种解决方法,即固定一个安全的应用程序,就像来自 system32 的任何应用程序一样,并编辑在其下创建的快捷方式(.lnk)文件%appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar以使其指向所需的应用程序,并更新其图标和名字。

问题

现在,我已经成功地以编程方式复制了几乎所有内容,除了最后一步,即用我们要固定的应用程序名称重命名快捷方式。

但这里有一个棘手的部分,如果您已经固定了一个应用程序并且只是在 中正常重命名它(rclick->rename->type something->hit enter%appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar,那么您已经损坏了它。如果您杀死exporer.exe并重新启动它,您会注意到固定项目已变得无法使用,例如:

空白文件

正确的方法是通过rclick->properties->general->change file name->press ok. 但是,我们如何以编程方式重现这一点?

代码

如果您的系统语言不是fr-FR,则需要更新TaskBarHelper初始化程序。在抛出异常的位置附近的异常和注释中提供了说明。

public static class TaskBarHelper
{
    // this solution is dependent on the os language, so we need to check if we are using the correct text for the os language
    private static readonly string PinActionText, UnpinActionText;
    static TaskBarHelper()
    {
        switch (CultureInfo.InstalledUICulture.Name)
        {
            case "fr-FR": 
                PinActionText = "Épingler à la &barre des tâches";
                UnpinActionText = "Détacher de la b&arre des tâches";
                break;

            default: // find the action text for this language
                var appPath = Directory.GetFiles(Environment.SystemDirectory, "*.exe").First();
                var actions = GetItemVers(appPath);

                throw new NotSupportedException("Please add the right actions' text from the followings : \n" + 
                    string.Join("\n", actions.Select(x => x.Name)));
        }
    }

    public static void Pin(string appPath)
    {
        if (!File.Exists(appPath)) throw new FileNotFoundException(appPath);

        GetItemVers(appPath)
            .First(x => x.Name == PinActionText)
            .DoIt();
    }
    public static void Unpin(string appPath)
    {
        if (!File.Exists(appPath)) throw new FileNotFoundException(appPath);

        GetItemVers(appPath)
            .First(x => x.Name == UnpinActionText)
            .DoIt();
    }

    public static void PinNetworkApplication(string appPath)
    {
        if (!File.Exists(appPath)) throw new FileNotFoundException(appPath);

        //pin a random application from sys32
        var randomApp = new DirectoryInfo(Environment.SystemDirectory).GetFiles("*.exe").First();
        //if (TaskBarHelper.GetPinnedFolderItems().Any(x => randomApp.FullName.Equals(x.GetLink().Path, StringComparison.InvariantCultureIgnoreCase)))
        try { Unpin(randomApp.FullName); } catch { }
        Pin(randomApp.FullName);

        //find its lnk file in the pinned items
        var pinFile = TaskBarHelper.GetPinnedFolderItems().Single(x => randomApp.FullName.Equals(x.GetLink().Path, StringComparison.InvariantCultureIgnoreCase));
        var pinLink = pinFile.GetLink();

        //DispatchUtility.GetType(pinFile as object, false).GetMethods().Select(m => m.Name).Dump("File");
        //DispatchUtility.GetType(pinLink as object, false).GetMethods().Select(m => m.Name).Dump("Link");
        //ExposeMethods(pinFile as object);
        //ExposeMethods(pinLink as object);

        //rename the lnk file, but we can't rename it *properly*
        pinLink.Path = appPath;
        pinLink.SetIconLocation(appPath, 0);
        pinLink.Save();

        //all these corrupt the taskbar
        //pinFile.Name = Path.GetFileNameWithoutExtension(appPath);
        //File.Move(pinFile.Path, Path.Combine(
        //Path.GetDirectoryName(pinFile.Path), 
        //      Path.GetFileNameWithoutExtension(appPath) + ".lnk")); 
        //Util.Cmd(string.Format("rename \"{0}\" \"{1}\"", //btw, this is basically like Win+R
        //      pinFile.Path as string, 
        //      Path.GetFileNameWithoutExtension(appPath) + ".lnk").Dump());
    }

    public static void Refresh()
    {
        foreach (var process in Process.GetProcessesByName("explorer"))
            process.Kill();

        Process.Start(Path.Combine(Environment.GetEnvironmentVariable("windir"), "explorer.exe"));
    }

    //get all item from the file's context menu in explorer
    private static IEnumerable<dynamic> GetItemVers(string appPath) //FolderItemVerb
    {
        var fi = new FileInfo(appPath);
        if (!fi.Exists) throw new FileNotFoundException(fi.FullName);

        dynamic shell = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        var folder = shell.NameSpace(fi.Directory.FullName);
        var file = folder.ParseName(fi.Name);

        var actions = file.Verbs();
        for(int i = 0; i < actions.Count(); i++)
            yield return actions.Item(i);
    }

    //get all pinned items from task bar
    public static IEnumerable<dynamic> GetPinnedFolderItems()
    {
        var taskBarPath = Path.Combine(
            Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData),
            @"Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar");

        dynamic shell = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        var folder = shell.NameSpace(taskBarPath);

        return new DirectoryInfo(taskBarPath).GetFiles("*.lnk")
            .Select(x => folder.ParseName(x.Name));
    }
}

TL;博士

如何以rclick->properties->general->change file name->press ok编程方式重现?

4

0 回答 0