2009-06-24 15 views
6

Perl komut dosyasını kullanarak Windows klasörünü değiştirmenin bir yolu var mı?Perl komut dosyasını kullanarak Windows klasör simgesini değiştirmenin bir yolu var mı?

Amacım, "xxx_documents" klasörünün normal simgesini başka bir simgeye dönüştürmektir. Senaryoyu, tüm sürücüye bakacak şekilde yürütmeliyim.

Sürücüde çok sayıda klasör var. "Belgeler" (ör. "Xxx_documents" veya sadece "belgeler") adında her klasörü aramak ve simgesini "%SystemRoot%\system32\SHELL32.dll" kitaplığından biriyle değiştirmek zorundayım.

Bu mümkün Perl? Bana yardımcı olan herkese teşekkürler.

cevap

8

Bunu Perl ile yapabilirsin. Windows, her klasörde gizli bir sistem Dekstop.ini dosyasını kullanarak dizin simgelerini denetler. içindekiler şöyle görünür: Windows XP'de

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

(ve diğer sistemlerde varsayalım), simge 41 bir ağaçtır. Yukarıdaki kod çalıştırırsanız

#!/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(); 

, bu belirlesin: Windows bu onu oluşturmak için Win32API::File içine kazmak gerekir anlamına gelir, bu dosyanın açıkça işe yaraması için bir sistem dosya olarak ayarlanabilir gerektirir Geçerli dizinin bir ağacın simgesi. Gezgini değiştirmek için kaşif listesini yenilemeniz gerekebilir.

Simgeleri değiştirmenin bir yoluna sahip olduğumuza göre, şimdi bütün bir sürücüden geçebilir ve desenimizle eşleşen her klasörü değiştirebiliriz. Biz File::Find, ya da alternatiflerden birine (örneğin File::Find::Rule veya File::Next) ile oldukça kolayca yapabilirsiniz:

#!/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(); 
} 

Ne yazık ki, sadece dizin şu anda varsa ikon sadece değişti alır tesbit ettik , ya da bir kez vardı, bir simge ... dizinin kendisi üzerinde ayarlanmış bir öznitelik var, Windows, bir Desktop.ini dosya için bakmak neden, ama ben ne olduğunu anlamaya hayatım için yapamam. Bu nedenle, yukarıdaki çözüm eksiktir; Ayrıca, simgeyi eklediğimiz dizindeki öznitelikleri bulmalı ve düzeltmeliyiz.

Paul

+3

http://msdn.microsoft.com/en-us/library/cc144102.aspx adresine göre, sistem klasörünü de içeren klasöre ayarlamanız gerekir. – ephemient

+0

http://www.google.com/search?btnI=&q=%22Customizing+Folders+with+Desktop.ini%22 –

0

yenilemek için simgeyi almak için, bazı SHChangeNotify büyü çağırmak zorunda kalacak (C++ örnek, ama fikir olsun):

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); 
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 
İlgili konular