是否可以创建一个可以根据文件位置重定向文件夹图标目录的程序?



Background

哟,伙计们。所以首先,这是一个动漫文件夹,它用不同的文件夹图标显示我所有的动漫系列。所有上述自定义图标都位于名为"icons"的隐藏文件夹中。这种格式是我在相应年份的其他文件夹中列出的格式。

问题/情况

众所周知,当我们移动/篡改"图标"文件夹或动漫文件夹的目录时,链接会断开,动漫系列的自定义图标会消失。可以通过再次分配自定义图标或重命名目录来解决此问题。

我倾向于将动漫文件夹复制到其他硬盘驱动器。我想知道是否可以创建一个程序,根据动漫文件夹所在的位置自动修复其目录链接。

例如,假设我从目录"G:\2018"复制 2018 动漫文件夹并将其放在桌面中。比方说,慢启动的自定义文件夹图标仍然是 G:\2018\icons\Slow_Start_Folder_Icon.ico。程序运行时,将自动将目录链接更改为 C:\Users****\Desktop\2018\icons\Slow_Start_Folder_Icon.ico。当然,与其他动漫文件夹同时进行。

任何有启发性的答案都非常感谢。提前也谢谢。

更新3:这是我目前的工作代码,其中包含从@Jimi获得的想法和建议。经过测试,它对我有用。

private static void UpdateIcons() //for updating folder icons to new directory
{
int start, end;
string filedir = Environment.CurrentDirectory, olddir = null, newdir = null;
IEnumerable<string> Ini = Directory.EnumerateFiles(filedir, "desktop.ini", SearchOption.AllDirectories);
foreach (string deskini in Ini)
{
File.SetAttributes(deskini, FileAttributes.Archive);
foreach (var line in File.ReadAllLines(deskini))
{
if (line.Contains("IconResource"))
{
start = line.IndexOf("icons");
Console.WriteLine(line);
Console.WriteLine(line.Length.ToString());
Console.WriteLine(line.IndexOf("icons").ToString());
if (line.Contains(","))
{
end = line.IndexOf(",");
olddir = line.Substring(start, (end - start));
Console.Write(end - start);
}
else
{
end = line.Length - 1;
Console.Write(end);
olddir = line.Substring(start, (end - start + 1));
Console.Write(end - start);
}

newdir = File.ReadAllText(deskini);
newdir = newdir.Replace(line, "IconResource=" + filedir + "\" + olddir);
File.WriteAllText(deskini, newdir, Encoding.Unicode);
Console.WriteLine(olddir);
Console.WriteLine(newdir);
}
}
File.SetAttributes(deskini, FileAttributes.Hidden);
}
}

应用程序接受命令行参数,可在其中指定图标存储库(文件夹名称(。如果未提供任何内容,则假定图标存储库名为"icons",位于当前执行路径中。

Assembly.GetExecutingAssembly用于确定可执行路径。Location属性返回标准格式的 Path。

Directory.GetDirectory 用于获取当前路径中目录的目录列表,包括子目录。然后,当前路径和图标目录将从列表中排除,因为这些文件夹不受自定义。

Directory.GetFiles(( 用于构建包含在 Icons 文件夹中的图标文件列表。

要更新文件夹自定义(资源管理器在更新这些更改时可能有些懒惰:在没有其他指示的情况下,它会使用IconCache.db存储(,我们调用 SHGetSetFolderCustomSettings。
此命令行管理程序 API 创建或更新位于每个自定义文件夹中的desktop.ini文件。此文件引用用作文件夹自定义图标的图标。
此功能允许快速更新文件夹新方面。在这种情况下,更新是即时的。无需删除图标缓存或重新启动资源管理器。

相关信息:
如何使用桌面自定义文件夹.ini
本文档是 Windows 命令行管理程序文档《命令行管理程序之书》的一部分。
SHFOLDERCUSTOMSETTINGS的旧定义,在官方文档中缺失。

将此代码编译为Release,并将可执行文件复制到列出自定义子文件夹的上层文件夹中。

注意:
在此示例中,我从图标存储库中随机选择要分配给文件夹的图标(使用Random值(。您需要定义自己的逻辑才能将正确的图标分配给特定文件夹。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
public enum FolderCustomSettingsMask : uint
{
InfoTip = 0x00000004,
Clsid = 0x00000008,
IconFile = 0x00000010,
Logo = 0x00000020,
Flags = 0x00000040
}
public enum FolderCustomSettingsRW : uint
{
Read = 0x00000001,
ForceWrite = 0x00000002,
ReadWrite = Read | ForceWrite
}
[SecurityCritical]
[DllImport("Shell32.dll", CharSet = CharSet.Auto)]
static extern uint SHGetSetFolderCustomSettings(ref SHFOLDERCUSTOMSETTINGS pfcs, string pszPath, FolderCustomSettingsRW dwReadWrite);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct SHFOLDERCUSTOMSETTINGS
{
public uint dwSize;
public FolderCustomSettingsMask dwMask;
public IntPtr pvid;
public string pszWebViewTemplate;
public uint cchWebViewTemplate;
public string pszWebViewTemplateVersion;
public string pszInfoTip;
public uint cchInfoTip;
public IntPtr pclsid;
public uint dwFlags;
public string pszIconFile;
public uint cchIconFile;
public int iIconIndex;
public string pszLogo;
public uint cchLogo;
}

static void Main(string[] args)
{
string CurrentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string IconsFolder = args.Length > 0 ? args[0] : Path.Combine(CurrentPath, @"icons");
UpdateFolderIcons(CurrentPath, IconsFolder);
Console.WriteLine($"Press any key to terminate...");
Console.ReadKey();
}

[SecuritySafeCritical]
public static void UpdateFolderIcons(string BaseFolder, string IconsFolder)
{
Console.WriteLine($"Current path: {BaseFolder}");
Console.WriteLine($"Processing...");
Console.WriteLine();
List<string> ExcludeDirList = new List<string>() {BaseFolder, IconsFolder};
List<string> DirList = Directory.GetDirectories(BaseFolder, "*", SearchOption.AllDirectories).ToList();
DirList = DirList.Except(ExcludeDirList).ToList();
if (DirList.Count == 0) {
Console.WriteLine($"No directories found!");
return;
}
Console.WriteLine($"{DirList.Count} Directories found");
Console.WriteLine("Updating...");
Console.WriteLine();
int UpdateCount = 0;
List<string> IconNames = Directory.GetFiles(Path.Combine(BaseFolder, IconsFolder), "*").ToList();
if (IconNames.Count == 0) {
Console.WriteLine($"No icons found in {IconsFolder}");
return;
}
foreach (string sPath in DirList)
{
string IconName = IconNames[random.Next(0, IconNames.Count)];
SHFOLDERCUSTOMSETTINGS FolderSettings = new SHFOLDERCUSTOMSETTINGS  {
dwMask = FolderCustomSettingsMask.IconFile,
pszIconFile = IconName,
iIconIndex = 0
};
uint hResult = SHGetSetFolderCustomSettings(
ref FolderSettings, sPath + char.MinValue, FolderCustomSettingsRW.ForceWrite);
UpdateCount += 1;
}
Console.WriteLine($"{UpdateCount} Files Updated");
Console.WriteLine();
}

最新更新