【问题标题】:Is there is a way to change a Windows folder icon using a Perl script?有没有办法使用 Perl 脚本更改 Windows 文件夹图标?
【发布时间】:2010-11-05 10:17:31
【问题描述】:

有没有办法使用 Perl 脚本更改 Windows 文件夹图标?

我的目的是将“xxx_documents”文件夹的普通图标更改为其他图标。我必须以照顾整个驱动器的方式运行脚本。

驱动器包含许多文件夹。我必须搜索每个名为“documents”的文件夹(例如“xxx_documents”或简称为“documents”)并将其图标更改为 "%SystemRoot%\system32\SHELL32.dll" 库中的一个。

这在 Perl 中可能吗?感谢所有帮助我的人。

【问题讨论】:

    标签: windows perl shell


    【解决方案1】:

    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】:

      要刷新图标,您必须调用一些 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);
      

      【讨论】:

        【解决方案3】:

        你当然可以用 Perl 做到这一点。 Windows 通过使用每个文件夹中隐藏的 systemDekstop.ini 文件来控制目录图标。内容看起来像这样:

         [.ShellClassInfo]
         IconFile=%SystemRoot%\system32\SHELL32.dll
         IconIndex=41
        

        在 Windows XP 上(我假设在其他系统上),图标 41 是一棵树。 Windows 需要将此文件显式设置为 system 文件才能工作,这意味着我们需要深入研究 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::RuleFile::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 文件,但我无法终生弄清楚它是什么。因此,上述解决方案是不完整的;我们还需要在添加图标的目录中找到并修复属性。

        保罗

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-12
        • 2021-03-20
        • 1970-01-01
        • 2012-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多