2009-10-24 10 views
2

J'essaie d'émuler la capacité de RapidCRC à vérifier les valeurs crc32 dans les noms de fichiers sur Windows Vista Ultimate 64-bit. Cependant, je semble courir dans une sorte de limitation des arguments.Pourquoi ne puis-je pas utiliser plus de 20 fichiers avec mon script Perl et SendTo de Windows?

j'ai écrit un script Perl rapide, créé un fichier batch pour appeler, puis placé un raccourci vers le fichier batch dans %APPDATA%\Microsoft\Windows\SendTo

Cela fonctionne très bien lorsque je sélectionne 20 fichiers ou moins, faites un clic droit et " envoyer à "mon script de fichier batch. Cependant, rien ne se passe du tout lorsque je sélectionne plus que cela. Je soupçonne qu'il y a un caractère ou un nombre d'arguments limités quelque part.

J'espère qu'il me manque quelque chose de simple et que la solution ou une solution de contournement n'est pas trop douloureuse.

Références:

fichier batch (crc32_inline.bat):

crc32_inline.pl %* 

Perl note:

J'utilise (fraise) perl v5.10.0

J'ai C: \ strawberry \ perl \ bin dans mon chemin, où existe crc32.bat.

script perl (crc32_inline.pl):

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Cwd; 
use English qw(-no_match_vars); 
use File::Basename; 

$OUTPUT_AUTOFLUSH = 1; 

my $crc32_cmd = 'crc32.bat'; 
my $failure_report_basename = 'crc32_failures.txt'; 
my %failures =(); 

print "\n"; 
foreach my $arg (@ARGV) { 

    # if the file has a crc, check to see if it matches the calculated 
    # crc. 
    if (-f $arg and $arg =~ /\[([0-9a-f]{8})\]/i) { 
    my $crc = uc $1; 
    my $basename = basename($arg); 
    print "checking ${basename}... "; 
    my $calculated_crc = uc `${crc32_cmd} "${arg}"`; 
    chomp($calculated_crc); 
    if ($crc eq $calculated_crc) { 
     print "passed.\n"; 
    } 
    else { 
     print "FAILED (calculated ${calculated_crc})\n"; 
     my $dirname = dirname($arg); 
     $failures{$dirname}{$basename} = $calculated_crc; 
    } 
    } 
} 

print "\nReport Summary:\n"; 
if (scalar keys %failures == 0) { 
    print " All files OK\n"; 
} 
else { 
    print sprintf(" %d/%d files failed crc32 validation.\n" . 
       " See %s for details.\n", 
       scalar keys %failures, 
       scalar @ARGV, 
       $failure_report_basename); 

    my $failure_report_fullname = $failure_report_basename; 
    if (defined -f $ARGV[0]) { 
    $failure_report_fullname 
     = dirname($ARGV[0]) . '/' . $failure_report_basename; 
    } 

    $OUTPUT_AUTOFLUSH = 0; 
    open my $fh, '>' . $failure_report_fullname or die $!; 
    foreach my $dirname (sort keys %failures) { 
    print {$fh} $dirname . "\n"; 
    foreach my $basename (sort keys %{$failures{$dirname}}) { 
     print {$fh} sprintf(" crc32(%s) basename(%s)\n", 
          $failures{$dirname}{$basename}, 
          $basename); 
    } 
    } 
    close $fh; 
    $OUTPUT_AUTOFLUSH = 1; 
} 

print sprintf("\n%s done! (%d seconds elapsed)\n" . 
       "Press enter to exit.\n", 
       basename($0), 
       time() - $BASETIME); 
<STDIN>; 

Répondre

1

Je recommande simplement de mettre un raccourci vers votre script dans le « Envoyer à » répertoire au lieu de le faire via un fichier batch (qui fait l'objet à cmd.exe s limites sur la longueur de la ligne de commande).

+1

L'exécution de la commande directement à partir du menu Envoyer vers est également soumise à la limite de la longueur de la ligne de commande. –

+0

J'ai modifié les raccourcis pour appeler 'perl' à "" qui semble fonctionner. La création des fichiers batch était un oubli stupide de ma part. J'avais initialement créé des raccourcis vers les scripts perl eux-mêmes, en espérant que l'association de fichiers perl les rendrait exécutables. Malheureusement, j'avais tort, et ils ne sont pas apparus dans le menu d'envoi. Envelopper le script dans un fichier batch semblait fonctionner (au moins, il est apparu dans le menu), avec la limitation d'entrée notable. Ce n'est que plus tard que je me suis rappelé qu'un raccourci Windows est plus comme une commande qu'un lien symbolique. Merci! – vlee

+0

Rob Kennedy: 'cmd.exe' a une limite de longueur de ligne d'environ 8190 caractères. La longueur maximale que vous pouvez passer 'CreateProcess' est de 32767 caractères. Faites attention à ce que vous demandez exactement: http://blogs.msdn.com/oldnewthing/archive/2003/12/10/56028.aspx – Joey