Вы уверены, что можете сделать это с 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();
}
К сожалению, я только что обнаружил, что значок only изменяется, если каталог в настоящее время имеет или когда-то имел значок ... Очевидно, в самом каталоге установлен атрибут, который вызывает Windows ищет файл Desktop.ini
, но я не могу понять, что это такое. Таким образом, вышеуказанное решение является неполным; нам также нужно найти и исправить атрибуты в каталоге, куда мы добавляем значок.
Пол