语境
由于工作机器上的安全策略,我无法固定网络驱动器上的应用程序。但是,我找到了一种解决方法,即固定一个安全的应用程序,就像来自 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
编程方式重现?