是否有办法使用Perl脚本更改Windows文件夹图标?
我的目的是将“xxx_documents”文件夹的普通图标更改为其他图标。我必须以一种照顾整个驱动器的方式运行脚本。
驱动器包含许多文件夹。我必须搜索名为“documents”的每个文件夹(例如“xxx_documents”或简称“文档”),并将其图标更改为"%SystemRoot%\system32\SHELL32.dll"
库中的图标。
Perl有可能吗?感谢所有帮助我的人。
答案 0 :(得分:8)
你确定可以用Perl做到这一点。 Windows通过使用每个文件夹中的隐藏系统Dekstop.ini
文件来控制目录图标。内容看起来像这样:
[.ShellClassInfo]
IconFile=%SystemRoot%\system32\SHELL32.dll
IconIndex=41
在Windows XP上(我假设在其他系统上),图标41是一棵树。 Windows要求将此文件显式设置为系统文件才能生效,这意味着我们需要深入了解Win32API::File
来创建它:
#!/usr/bin/perl
use strict;
use warnings;
use Win32API::File qw(createFile WriteFile fileLastError CloseHandle);
my $file = createFile(
'Desktop.ini',
{
Access => 'w', # Write access
Attributes => 'hs', # Hidden system file
Create => 'tc', # Truncate/create
}
) or die "Can't create Desktop.ini - " . fileLastError();
WriteFile(
$file,
"[.ShellClassInfo]\r\n" .
"IconFile=%SystemRoot%\\system32\\SHELL32.dll\r\n" .
"IconIndex=41\r\n",
0, [], []
) or die "Can't write Desktop.ini - " . fileLastError();
CloseHandle($file) or die "Can't close Desktop.ini - " . fileLastError();
如果您运行上面的代码,它应该将当前目录的图标设置为树。在资源管理器获取更改之前,您可能需要刷新目录列表。
现在我们有了改变图标的方法,现在我们可以浏览整个驱动器并更改与我们的模式匹配的每个文件夹。我们可以使用File::Find
或其中一个替代方案(例如File::Find::Rule
或File::Next
)轻松完成此操作:
#!/usr/bin/perl
use strict;
use warnings;
use File::Find qw(find);
use Win32API::File qw(createFile WriteFile fileLastError CloseHandle);
my $topdir = $ARGV[0] or die "Usage: $0 path\n";
find( \&changeIcon, $topdir);
sub changeIcon {
return if not /documents$/i; # Skip non-documents folders
return if not -d; # Skip non-directories.
my $file = createFile(
"$_\\Desktop.ini",
{
Access => 'w', # Write access
Attributes => 'hs', # Hidden system file
Create => 'tc', # Truncate/create
}
) or die "Can't create Desktop.ini - " . fileLastError();
WriteFile(
$file,
"[.ShellClassInfo]\r\n" .
"IconFile=%SystemRoot%\\system32\\SHELL32.dll\r\n" .
"IconIndex=41\r\n",
0, [], []
) or die "Can't write Desktop.ini - " . fileLastError();
CloseHandle($file) or die "Can't close Desktop.ini - " . fileLastError();
}
不幸的是,我刚刚发现,如果目录中有一个图标仅会被更改,或者曾经有一个图标......显然有一个属性是在目录本身上设置的导致Windows查找Desktop.ini
文件,但我不能为我的生活弄清楚它是什么。因此,上述解决方案是不完整的;我们还需要在我们添加图标的目录中找到并修复属性。
保
答案 1 :(得分:2)
1
[.ShellClassInfo]
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21790
InfoTip=@%SystemRoot%\system32\shell32.dll,-12689
IconResource=%SystemRoot%\system32\imageres.dll,-108
IconFile=%SystemRoot%\system32\shell32.dll
IconIndex=-237
2
[.ShellClassInfo]
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21803
InfoTip=@%SystemRoot%\system32\shell32.dll,-12689
IconResource=%SystemRoot%\system32\imageres.dll,-3
答案 2 :(得分:0)
要获取要刷新的图标,您必须调用一些SHChangeNotify voodoo(C ++示例,但您明白了这一点):
int imageIndex = Shell_GetCachedImageIndexW(wPath, GetSyncFolderIconIndex(), 0);
if (imageIndex != -1)
{
// If we don't do this, and we EVER change our icon, Explorer will likely keep
// using the old one that it's already got in the system cache.
SHChangeNotify(SHCNE_UPDATEIMAGE, SHCNF_DWORD | SHCNF_FLUSHNOWAIT, &imageIndex, NULL);
}
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATHW | SHCNF_FLUSHNOWAIT, wPath, NULL);