Recentemente, criei um script em Perl que faz isso exatamente. Quando você inicia este script, ele pesquisa se há um arquivo ZIP mais recente, copia, extrai, modifica um arquivo de configuração e inicia o EXE. Talvez você não queira fazer tudo isso, mas postarei aqui se quiser modificá-lo / usá-lo.
#!/usr/bin/perl
# get_latest_executable.pl v0.5
# Usage: perl get_latest_executable.pl test4|test6 [country] [language]
###############
# YD @ 02/09/2011
# 05/09/2011 Multiple transparent compression options
# Fixed config file backup
# Removed useless debug code
# 12/09/2011 Added external configuration file
# Removed internal arrays with options, script argument is trusted now
# 15/09/2011 Added informing latest executable date
# More comments and intro
# 19/09/2011 Bug retreiving versions higher than 99 (fixed)
# Now checking latest executable is done on file creation time and no longer using version
# 27/09/2011 Fixed extra trailing \ on destination path
# 28/09/2011 Added commenting out all user.dll's updateUserConfiguration entry
# Now user.dll file is parsed until the end, and does not stop when first searched entry is found
###############
use strict;
use File::stat;
use File::Path qw(make_path remove_tree);
use File::Copy;
use constant VERSION => "v0.5";
use constant TIMESTAMP_FORMAT => "%02d:%02d %02d/%02d/%4d"; # Formato del informe de fecha
##########
# Args
##########
use constant MIN_ARGS => 0;
use constant MAX_ARGS => 2;
##########
# Indexes
##########
use constant IDX_TEST4 => 0;
use constant IDX_TEST6 => 1;
my $executable_branch;
##########
# Paths
##########
my $path_source;
# Where to copy the executable in local
my $path_destination;
# Where to search for latest executable
my $path_latest_executable;
##########
# File names
##########
# SGCV10 executable name
my $executable_name = 'gccom.exe';
# SGCV10 config file name
my $config_file = "user.dll";
# Script configuration file
my $config = "config.txt";
##########
# Compressors
##########
my @compressors = ('"C:\Archivos de programa-Zipz.exe" x -y ', '"C:\Archivos de programa\WinZip\winzip32.exe" -e ');
##########
# SGCV10 configuration
##########
my $do_config_changes = "";
my $backup_prefix = '.bak';
my $country = "es";
my $country_option = '(^COUNTRY=)';
my $lang = "ES";
my $lang_option = '(^LANGUAGE=)';
my $update_option = '^updateUserConfiguration=';
##########
# Script configuration
##########
my $source = '^SOURCE=(.*)\n';
my $destination = '^DESTINATION=(.*)\n';
# Checks arguments received by the script
sub check_args()
{
if ($#ARGV > MAX_ARGS || $#ARGV < MIN_ARGS)
{
print(STDERR "Numero de argumentos incorrecto\n");
print(STDERR "Uso: perl get_latest_executable.pl test4|test6 [country] [language]\n");
exit();
}
$executable_branch = $ARGV[0];
if ($#ARGV >= 1)
{
$do_config_changes = "1";
$country = $ARGV[1];
}
if ($#ARGV == 2)
{
$lang = uc($ARGV[2]);
}
}
# Returns true if file "a" is newer than file "b"
sub is_newer_version
{
my ($a_path, $b_path) = @_;
my $ret = "1";
if ($b_path ne "")
{
my $a_time = stat($a_path)->mtime;
my $b_time = stat($b_path)->mtime;
$ret = $a_time > $b_time;
}
return $ret;
}
# Receives executable directory
# Returns latest zip full path
sub get_latest_zip_full_path
{
my $path = shift;
my $ret;
if (-d $path)
{
opendir(DH, $path) or die ("No se pudo abrir el directorio: $path\n");
my @dir = readdir(DH);
close(DH);
my $newest = 0;
for(@dir)
{
my $full_path = $path.$_;
if (-f $full_path && $_ =~ m/zip/i)
{
my $cur_file_time = stat($full_path)->mtime;
if($cur_file_time > $newest)
{
$newest = $cur_file_time;
$ret = $full_path;
}
}
}
}
return $ret;
}
# Returns true if local executable is OLDER than remote executable, false otherwise
# Creates local directory if not found, deletes older executable .ZIP and directory
sub check_local_delete
{
my ($local_dir, $local_latest, $remote_path) = @_;
my $ret = "";
# Local directory exists
if(-d $local_dir)
{
if (is_newer_version($remote_path, $local_latest))
{
print(STDERR "Borrando ejecutable obsoleto: $local_latest\n");
# Delete older local ZIP
unlink($local_latest);
# Delete old directory
$local_latest =~ s/\.zip//;
if (-d $local_latest)
{
remove_tree($local_latest);
}
$ret = "1";
}
}
# Local directory does not exist, create it and return remote newer
else
{
make_path($local_dir);
$ret = "1";
}
return $ret;
}
# Given a full path, returns filename only
sub get_filename_from_full_path
{
my $full_path = shift;
my $ret = reverse($full_path);
$ret =~ m/\/;
$ret = $';
$ret = reverse($ret);
return $ret;
}
# Modifies SGCv10 configuration
sub make_config_changes
{
my $path = shift;
my $config_path = $path.$config_file;
if (-f $config_path)
{
open(FD, '<'.$config_path);
my @config = <FD>;
close(FD);
# Backup original file (only if not backed up already!!!)
if (!(-f $config_path.$backup_prefix))
{
copy($config_path, $config_path.$backup_prefix);
}
# Modify it
my $i = 0;
while($i <= $#config)
{
if ($config[$i] =~ /$country_option/)
{
$config[$i] = $1.$country."\n";
}
if ($config[$i] =~ /$lang_option/)
{
$config[$i] = $1.$lang."\n";
}
if ($config[$i] =~ /$update_option/)
{
$config[$i] = "//" . $config[$i];
}
$i++;
}
# Write it
open(FD, '>'.$config_path);
print(FD @config);
close(FD);
}
else
{
print(STDERR "WARNING: config file $config_path not found!\n");
}
}
# Selects best command to decompress with
sub get_best_compressor
{
my $ret;
my $i = 0;
my $found = "";
while($i <= $#compressors && !$found)
{
$compressors[$i] =~ m/\"(.*)\"/;
if (-f $1)
{
$ret = $compressors[$i];
$found = "1";
}
}
if (!$found)
{
$ret = -1;
}
return $ret;
}
# Reads and applies configuration file
sub read_config
{
open(FD, '<'.$config) or die "No se encontro el fichero de configuracion $config\n";
my @config = <FD>;
close(FD);
# Source
my @source_list = grep(/$source/, @config);
my $src = $source_list[0];
$src =~ /$source/;
$src = $1;
if (substr($src, -1, 1) ne "\")
{
$src .= "\";
}
$path_latest_executable = uc("$src$executable_branch\");
# Destination
my @dest_list = grep(/$destination/, @config);
$path_destination = $dest_list[0];
$path_destination =~ /$destination/;
$path_destination = uc($1);
if (substr($path_destination, -1, 1) ne "\")
{
$path_destination .= "\";
}
}
# Formatea el tiempo
sub format_timestamp
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = @_;
return sprintf(TIMESTAMP_FORMAT, $hour, $min, $mday, $mon+1, $year+1900);
}
# Basurilla
sub intro
{
print(STDERR "AutoEjecutable " . VERSION . " by Obi Perl Kenobi\n\n");
}
#############
# MAIN
#############
# Show intro
intro();
# Checking arguments
check_args();
# Read configuration file
read_config();
if (!(-d $path_latest_executable))
{
print(STDERR "No se ha encontrado el directorio origen $path_latest_executable\n");
exit();
}
# Getting latest executable
my $latest_zip_full_path = get_latest_zip_full_path($path_latest_executable);
# Getting time stamp
my $latest_zip_time = format_timestamp(localtime(stat($latest_zip_full_path)->mtime));
print(STDERR "Ultimo ejecutable disponible: $latest_zip_full_path -> $latest_zip_time\n");
# Checking if latest executable newer than local
$path_destination .= $executable_branch."\";
if (check_local_delete($path_destination, get_latest_zip_full_path($path_destination), $latest_zip_full_path))
{
print(STDERR "El ejecutable remoto es mas reciente ($latest_zip_time), copiando... ");
# Copying executable to local
copy($latest_zip_full_path, $path_destination);
}
else
{
print(STDERR "No hay cambios!\n");
}
my $path_aux = $path_destination.get_filename_from_full_path($latest_zip_full_path);
my $local_exe_dir = $path_aux;
$local_exe_dir =~ s/\.zip//;
$local_exe_dir .= "\";
if (-f $path_aux && !(-d $local_exe_dir))
{
# Choose extractor
my $extractor_command = get_best_compressor();
if ($extractor_command == -1)
{
print(STDERR "No se pudo encontrar ningun programa de descompresión. Por favor modifique las rutas en el script si no usa la instalación por defecto\n");
exit();
}
# Extract ZIP
chdir($path_destination);
print(STDERR "Extrayendo...\n");
$extractor_command .= '"' . $path_aux . '"';
system($extractor_command);
}
chdir($local_exe_dir);
if ($do_config_changes)
{
print(STDERR "Modificando configuracion para pais $country y lengua $lang...\n");
make_config_changes($local_exe_dir);
}
my $local_exe = '"' . $local_exe_dir.$executable_name . '"';
print(STDERR "Lanzando el ejecutable $local_exe de las $latest_zip_time\n");
system($local_exe);
A sub-rotina get_latest_zip_full_path () faz o que você está pedindo.
Ele usa um arquivo de configuração externo, da seguinte maneira:
SOURCE=J:\Ejecutables\
DESTINATION=D:\SGCv10\ejecutables\
Isso não funcionará "como está" para o seu problema. Sinta-se à vontade para modificar e usar como quiser, além de perguntar o que você quer.