2010-03-03 2 views
0

Мое современное мышление: мне нужен определенный модуль, который позволит мне получить доступ к USB-устройству. Кроме того, мне нужна какая-то деамонная вещь, которая будет уведомлять мой скрипт о любом входящем событии USB-соединения. И затем я просто использую некоторое регулярное выражение, чтобы найти файл, который я хочу скопировать, а затем выполнить копирование, возможно, с помощью некоторого модуля копирования файлов.Как автоматически копировать файлы на жесткий диск с USB-устройства при подключении через Perl?

Но я искал CPAN с ключевым словом «USB» только для того, чтобы найти действительно очень мало подходящих модулей, и этот, казалось бы, самый перспективный модуль, который называется Device :: USB, говорит, что он не поддерживает систему Windows. Я запускаю Windows XP SP3, кстати.

Я предполагаю, что такая автоматизация не должна быть слишком сложной с Perl. Но я просто застрял там.

Любые идеи? или любые другие предложения? Спасибо :)

UPDATE

Все не так легко, как и ожидалось. Уверен, у меня есть чему поучиться. Но, основываясь на моих существующих знаниях Perl, мне удалось написать сценарий make-do. Я здесь, чтобы учиться. Пожалуйста, прокомментируйте, где я могу улучшить свой код. Спасибо, как всегда :)

use warnings; 
use strict; 
use File::Find; 
use File::Copy; 

my $from = 'I:/'; #Volume letter for USB drive in my OS 
my $to = 'E:\Copy-to'; 

while (1) { 
    if (-e $from) { 
     last; 
    }else{ 
     sleep(30); 
    } 
} 

my @files; 
find(sub{ push @files, $File::Find::name if /pdf$/}, $from); #Find the PDF files in the USB drive for Copying experiment 

for (@files){ 
    copy ($_,$to); 
} 
+2

Проблема с поиском «USB» заключается в том, что USB принципиально не имеет к этому никакого отношения. Вы получите уведомление вставки из HAL, а не с USB, и вы будете взаимодействовать с файлами через файловую систему, а не USB. – hobbs

+0

@hobbs, спасибо, что рассказал мне об этом. – Mike

ответ

0

Если кто-то (возможно, ученик Perl, такой как я, который любит поиграть с Perl на ящике Windows), должен наткнуться на этот пост, я бы хотел, чтобы он/она увидел хорошее решение основной части моей проблемы, которая была щедро предоставленный Corian от Perlmonks и не будет введен в заблуждение, как когда я впервые посмотрел на @Pestilence (без обид :)), чтобы поверить, что Perl не может справиться с этой задачей красиво. Правда, Perl вполне способен справиться с такой работой и сделать это очень легко.

Следующий код наклеен (дословно) из ответа Коряна на мой вопрос, размещенный в Perlmonks. Источник here

#!/usr/bin/perl -w 
package main; 
use strict; 
use DBI; 
use Data::Dumper; 

my $dbh = DBI->connect('dbi:WMI:'); 

my $sth = $dbh->prepare(<<WQL); 
    SELECT * FROM __instanceoperationevent 
    WITHIN 5 
    WHERE TargetInstance ISA 'Win32_LogicalDisk' 
    and TargetInstance.Name != 'C:' 
WQL 
$sth->execute(); 

# loops forever 
while (defined (my $row = $sth->fetchrow_arrayref())) { 
    my $ev = $row->[0]; 

    # Windows XP only :(
    print "Class\t",$ev->Path_->Class,"\n"; 
    for (qw(Name DeviceID Caption MediaType InterfaceType)) { 
     print join "\t", $_, ($ev->TargetInstance->{$_} || '<none>'); 
     print "\n"; 
     if ($ev->Path_->Class eq '__InstanceCreationEvent') { 
      print "Device (letter) $ev->{TargetInstance}->{Name} added\n"; 
     } 
    } 
} 

Все кредиты идут на Corian, и я хотел бы сделать это CW.

1

В худшем случае опрашивать томами искать его (смотрите на подключенные диски каждые несколько секунд). Что-то вроде этого довольно сложно в Perl, если вы не хотите, чтобы ваши руки были грязными & подключились к системе событий Windows.

Идеально, очевидно, подключается к родной подсистеме USB-уведомлений Windows с C. Если на вашей ручке есть эмуляция CD-ROM, вы можете на нее наложить сценарий автозапуска. Я думаю, вам лучше придерживаться C, C++ или даже C# для этого типа вещей. Perl является гражданином второго класса в Windows.

+3

Удивительный Win32 :: API позволит вам работать с любой DLL. http://search.cpan.org/dist/Win32-API/API.pm С этим модулем и пониманием соответствующего API-интерфейсов Win32 не имеет большого значения. – daotoad

+2

Другой вариант: Inline :: C. http://search.cpan.org/dist/Inline/C/C.pod Здесь вы можете обернуть вызов API C в подпрограмме, вызываемой из другого кода Perl. – daotoad

+0

Эти ребята правы. Если вы смешиваете немного C с этим, это вполне выполнимо. – pestilence669