Вопрос по windows, perl, shell – Есть ли способ изменить значок папки Windows с помощью сценария Perl?

6

Есть ли способ изменить значок папки Windows с помощью сценария Perl?

Мое намерение состоит в том, чтобы изменить обычную иконку «xxx_documents» папка к другому значку. Я должен запустить скрипт таким образом, чтобы он позаботился обо всем диске.

Диск содержит много папок. Мне нужно искать каждую папку с именем «документы» (например, «xxx_documents» или просто «документы») и измените его значок на один из"%SystemRoot%\system32\SHELL32.dll" библиотека.

Это возможно в Perl? Спасибо всем, кто помогает мне с этим.

Ваш Ответ

3   ответа
2

1.

.ShellClassInfo]
[email protected]%SystemRoot%\system32\shell32.dll,-21790
[email protected]%SystemRoot%\system32\shell32.dll,-12689
IconResource=%SystemRoot%\system32\imageres.dll,-108
IconFile=%SystemRoot%\system32\shell32.dll
IconIndex=-237

2.

.ShellClassInfo]
[email protected]%SystemRoot%\system32\shell32.dll,-21803
[email protected]%SystemRoot%\system32\shell32.dll,-12689
IconResource=%SystemRoot%\system32\imageres.dll,-3
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);
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 файл, но я не могу понять, что это такое. Таким образом, вышеуказанное решение является неполным; нам также нужно найти и исправить атрибуты в каталоге, куда мы добавляем значок.

Паве

Согласно с Msdn.microsoft.com / EN-US / библиотека / cc144102.aspx Вам также необходимо установить системный атрибут в папке, в которой он находитс ephemient
Google.com / ... Brad Gilbert

Похожие вопросы