Hola
Verán tengo un problema con el módulo FileUtils.move...
Si estos 2 archivos existen:
1º - C:\ABC.mp3
2º - D:\ABC.mp3
Imaginen que tenemos el 2º archivo abierto (Reproduciendose en winamp por ejemplo)
Ahora intentamos usar FileUtils.move para mover el 2º archivo, al directorio 1º. El archivo obviamente no se puede reemplazar, el FileUtils.move dará "error de acceso" pero a pesar de eso, FileUtils.move elimina el archivo 1º y desaparece!.
Y entonces nos queda esto:
1º - (NADA)
2º - D:\ABC.mp3
¿Se puede hacer algún tipo de "test" para que no elimine el archivo a reemplazar si da Errno::EACCES?
Lo que quiero decir, Es que primero se asegure de que la operación no va a dar error, Para que no elimine el archivo 1ª si el 2º no se puede mover.
Creo que por ahí leí algo como: FileUtils.test.move pero no estoy seguro...
También he visto FileUtils::NoWrite, PEro no he visto ningún ejemplo de como usarlo, Ni tampoco se si sirve para lo que necesito.
Muchas gracias.
El code que tengo por si sirve para más información es este:
# -*- coding: UTF-8 -*-
# Mueve archivos desde un punto de origen hasta un punto de destino
# Pensado para usarlo como replazamiento del "SendTo" de Windows.
#
# (Requiere el uso de argumentos)
# Módulos
require "FileUtils"
require 'dl'
exit if Object.const_defined?(:Ocra)
# Variables constantes
BUTTONS_OKCANCEL = 1
BUTTONS_YESNO = 4
CLICKED_CANCEL = 2
CLICKED_YES = 6
CLICKED_NO = 7
# Métodos
def help()
print "\nSe requiere al menos 1 archivo de origen.\n\n\n"
print "Modo de empleo: \n\n"
print ' Mover.rb [Destino] [Archivo de origen 1] [Archivo de origen 2] [etc...]' + "\n\n\n"
print 'Ejemplo: (Mover tres archivos al directorio de destino "C:"' + "\n\n"
print ' Mover.rb "C:\" "D:\Archivo1.txt" "E:\Archivo2.jpg" "F:\Archivo3.mp3"' + "\n\n"
Process.exit
end
def message_box(txt, title='', buttons='')
user32 = DL.dlopen('user32')
msgbox = DL::CFunc.new(user32['MessageBoxA'], DL::TYPE_LONG, 'MessageBox')
r, rs = msgbox.call([0, txt, title, 3].pack('L!ppL!').unpack('L!*'))
return r
end
def force_move(source_file, dest_file)
FileUtils.mv $archivo, ARGV[0]
rescue Errno::EACCES
response = message_box("El archivo esta en uso:\n" + $archivo + "\n\n Reintentar?", "Reintentar?", BUTTONS_OKCANCEL)
if response == CLICKED_YES
retry
elsif response == CLICKED_CANCEL
Process.exit
end
end
# Control de errores
if ARGV.empty? == true
help()
elsif ARGV.length < 2
help()
elsif File.directory?(ARGV[0]) == false
print "\n El directorio de destino no existe: " + (ARGV[0]) + "\n"
Process.exit
end
for archivo in ARGV[1..ARGV.length].each
if File.exist?(archivo) == false
print "\n El archivo a mover no existe: " + archivo + "\n"
end
end
# Proceso
for $archivo in ARGV[1..ARGV.length].each
if File.exist?(ARGV[0] + "\\" + $archivo.split('\\').last)
response = message_box("Origen:\n" + $archivo + "\n\n Destino:\n " + ARGV[0] + "\\" + $archivo.split('\\').last + "\n\n El archivo de destino ya existe, Reemplazar archivo?", "Reemplazar archivo?", BUTTONS_YESNO)
if response == CLICKED_YES
force_move($archivo, ARGV[0])
elsif response == CLICKED_CANCEL
Process.exit
end
else
force_move($archivo, ARGV[0])
end
end
# Fin
Process.exit
Me he mirado todo el módulo Kernel, FileUtils, Sysread, test, filestat, Process::Sys, IO, IO::WaitReadable, IO::WaitWritable, IOError... y el ftools
No encuentro la manera de como averiguar si un proceso (Cualquiera) tiene abierto un archivo.
¿alguna ayuda? :(
EDITO:
Joder, con lo fácil que es hacerlo en batch... Pero no quiero depender de eso.
Supongo que tendré que buscar hasta encontrar alguna gema parecida al "CMDOW" para windows xD
Al final he recurrido a un programa de terceros (CMDOW) para windows...
Posteo el code pa quien lo quiera probar (Aviso que soy novato, pueden sobrar varias cosas pero funciona bien), Me ha costado mucho esfuerzo xD
Ahora es cuando debería sonar una melodia de VICTORY! I'm great! ::)
salu2
# Mueve archivos desde un punto de origen hasta un punto de destino
# Pensado para usarlo como replazamiento del "SendTo" de Windows.
#
# (Requiere el uso de argumentos)
# Modulos
require "FileUtils"
require 'dl'
exit if Object.const_defined?(:Ocra)
# Variables constantes
BUTTONS_OKCANCEL = 1
BUTTONS_YESNO = 4
CLICKED_CANCEL = 2
CLICKED_YES = 6
CLICKED_NO = 7
# Metodos
def help()
print "\nSe requiere al menos 1 archivo de origen.\n\n\n"
print "Modo de empleo: \n\n"
print ' Mover.rb [Destino] [Archivo de origen 1] [Archivo de origen 2] [etc...]' + "\n\n\n"
print ' Ejemplo: (Mover tres archivos al directorio de destino "C:"' + "\n\n"
print ' Mover.rb "C:\" "D:\Archivo1.txt" "E:\Archivo2.jpg" "F:\Archivo3.mp3"' + "\n\n"
Process.exit
end
def message_box(txt, title='', buttons='')
user32 = DL.dlopen('user32')
msgbox = DL::CFunc.new(user32['MessageBoxA'], DL::TYPE_LONG, 'MessageBox')
r, rs = msgbox.call([0, txt, title, 3].pack('L!ppL!').unpack('L!*'))
return r
end
def force_move(source_file, dest_file)
rescue Errno::EACCES
response = message_box("El archivo esta en uso:\n" + $archivo + "\n\n Reintentar?", "Reintentar?", BUTTONS_OKCANCEL)
if response == CLICKED_YES
Access($archivo, ARGV[0])
retry
elsif response == CLICKED_CANCEL
Process.exit
end
end
def reintentar(source_file, dest_file)
response = message_box("El archivo esta en uso:\n" + $archivo + "\n\n Reintentar?", "Reintentar?", BUTTONS_OKCANCEL)
if response == CLICKED_YES
Access($archivo, ARGV[0])
elsif response == CLICKED_NO
nil
elsif response == CLICKED_CANCEL
Process.exit
end
end
def Access(source_file, dest_file)
ENV['tmp'] = $archivo.split('\\').last
'cheat environment_variables --add'
puts %x[cmdow.exe | Find "%tmp:~0,30%" >NUL]
response = $?.exitstatus
if response == 0
reintentar($archivo, ARGV[0])
elsif response == 1
FileUtils.mv $archivo, ARGV[0]
end
end
# Control de errores
if ARGV.empty? == true
help()
elsif ARGV.length < 2
help()
elsif File.directory?(ARGV[0]) == false
print "\n El directorio de destino no existe: " + (ARGV[0]) + "\n"
Process.exit
end
for archivo in ARGV[1..ARGV.length].each
if File.exist?(archivo) == false
print "\n El archivo a mover no existe: " + archivo + "\n"
end
end
# Proceso
for $archivo in ARGV[1..ARGV.length].each
if File.exist?(ARGV[0] + "\\" + $archivo.split('\\').last)
force_move($archivo, ARGV[0])
response = message_box("Origen:\n" + $archivo + "\n\n Destino:\n " + ARGV[0] + "\\" + $archivo.split('\\').last + "\n\n El archivo de destino ya existe, Reemplazar archivo?", "Reemplazar archivo?", BUTTONS_YESNO)
if response == CLICKED_YES
Access($archivo, ARGV[0])
elsif response == CLICKED_NO
nil
elsif response == CLICKED_CANCEL
Process.exit
end
else
Access($archivo, ARGV[0])
end
end
# Fin
Process.exit
(http://img109.imageshack.us/img109/9308/prtscrcapturedh.jpg)
(http://img141.imageshack.us/img141/6283/prtscrcapture2w.jpg)
(http://img525.imageshack.us/img525/4986/prtscrcapture3w.jpg)
PD: El archivo de destino ya no se elimina al clickar "Reemplazar (SI)" porque primero comprueba si está en uso antes de usar el módulo FileUtils :)