MoveIt By Elektro H@cker
SO: Windows
Agradecimientos para "kicasta" y "RyogiShiki".
Descripción:
Mueve archivos desde un punto de origen hasta un punto de destino.
Está pensado para usarlo como complemento del "SendTo" de Windows, El cual no mueve archivos de un disco duro a otro.
Instrucciones:
1º Crear un acceso directo a una carpeta.
(http://img31.imageshack.us/img31/4581/prtscrcapture4s.jpg)
(http://img854.imageshack.us/img854/8615/prtscrcapture5t.jpg)
2º Abrir las propiedades del aceso directo.
(http://img813.imageshack.us/img813/9016/prtscrcapturex.jpg)
3º Añadir la ruta de este script a la propiedad "Destino".
(http://img256.imageshack.us/img256/4986/prtscrcapture3w.jpg)
Ejemplo destino: Ruby C:\Windows\MoveIt.rb "C:\Nueva carpeta"
Ejemplo destino (Script compilado a .exe): C:\Windows\System32\MoveIt.exe "C:\Nueva carpeta"
4º (Opcional) Guardar el acceso directo modificado en la carpeta "SendTo" (C:\Users\USUARIO\AppData\Roaming\Microsoft\Windows\SendTo)
(http://img28.imageshack.us/img28/603/prtscrcapture6.jpg)
(http://img706.imageshack.us/img706/9238/prtscrcapture7o.jpg)
NOTAS:
Este script requiere el uso de argumentos. (Uno para la ruta de destino y el otro para el/los archivo(s) a mover.)
Si la carpeta de destino no existe, se pregunta para crearla o no. (Si no se crea, no se pueden copiar los archivos y se cancelará el programa xD)
(http://img19.imageshack.us/img19/203/prtscrcapture2c.jpg)
Si el archivo de destino ya existe, Se pregunta por su reemplazamiento.
(http://img210.imageshack.us/img210/3330/prtscrcapturejn.jpg)
Si el archivo está siendo usado por el sistema, Se da lugar a reintentar o cancelar la operación.
(http://img263.imageshack.us/img263/4114/prtscrcapture2j.jpg)
Si el archivo de origen contiene el caracter ilegal "–" (u2013) se reemplaza por el caracter "-"
En equipos de 64 Bit,Hay que copiar el compilado (.exe) tanto a la carpeta "System32" como "SysWOW64" Si se quiere usar la propiedad "Destino" de la siguiente forma en el acceso directo:
(http://img585.imageshack.us/img585/1623/prtscrcaptureq.jpg)
El script compilado (No muestra la consola):
EDITADO: 07/03/2012
http://www.mediafire.com/?clyzd39xxlxzn0d
El script:
EDITADO: 07/03/2012
# -*- coding: UTF-8 -*-
# MoveIt v1.0 By Elektro H@cker
#
# SO: Windows
# Agradecimientos para "kicasta" y "RyogiShiki".
# Descripción:
# Mueve archivos desde un punto de origen hasta un punto de destino.
# Está pensado para usarlo como complemento del "SendTo" de Windows, El cual no mueve archivos de un disco duro a otro.
# Modo de empleo:
#
# 1º Crear un acceso directo a una carpeta.
# 2º Abrir las propiedades del aceso directo.
# 3º Añadir la ruta de este script a la propiedad "Destino".
#
# Ejemplo destino: Ruby C:\\MoveIt.rb "E:\Nueva carpeta"
# Ejemplo destino (Script compilado a .exe): C:\MoveIt.exe "E:\Nueva carpeta"
#
# 4º (Opcional) Guardar el acceso directo modificado en la carpeta "SendTo" (C:\Users\USUARIO\AppData\Roaming\Microsoft\Windows\SendTo)
#
# Notas:
#
# Este script requiere el uso de argumentos. (Uno para la ruta de destino y el otro para el/los archivo(s) a mover.)
#
# Si la carpeta de destino no existe, se pregunta para crearla o no. (Si no se crea, no se pueden copiar los archivos xD)
# Si el archivo de destino ya existe, Se pregunta por su reemplazamiento.
# Si el archivo está siendo usado por algún proceso abierto, Se da lugar a reintentar o cancelar la operación.
#
# En equipos de 64 Bit,Hay que copiar el compilado (.exe) tanto a la carpeta "System32" como "SysWOW64" Si se quiere usar la propiedad "Destino" de la siguiente forma en el acceso directo:
# MoveIt "C:\Nueva carpeta"
# RECORDATORIO
#
# Caracteres ilegales
#
# á : .gsub("ß", "á")
# é : .gsub("Ú", "é")
# í : .gsub("Ý", "í")
# ó : .gsub("¾", "ó")
# ú : .gsub("·", "ú")
# ¿ : .gsub("┐", "\u00BF")
# – : .gsub("\û", "\u2013")
# ´ : .gsub("\┤", "\u00B4")
# · : .gsub("\À", "\u00B7")
# ¬ : .gsub("\¼", "\u00AC")
# º : .gsub("\║", "\u00BA")
# ª : .gsub("\¬", "\u00AA")
#
# ¡ : FAIL :(
# ' : FAIL :(
#
# Convertir Handle a Hex
# puts 1272.to_s 16
# 0x + HandleHEX
# Modulos
require 'dl'
require "FileUtils"
require 'win32ole'
require 'win32/api'
include Win32
exit if Object.const_defined?(:Ocra)
# Variables globales y constantes
if ARGV.empty? == false
$DIR = (ARGV[0].encode('utf-8').gsub("ß", "á").gsub("Ú", "é").gsub("Ý", "í").gsub("¾", "ó").gsub("·", "ú").gsub("┐", "\u00BF").gsub("\û", "\u2013").gsub("┤", "\u00B4").gsub("\À", "\u00B7").gsub("\¬", "\u00AA").gsub("\¼", "\u00AC").gsub("\║", "\u00BA"))
$DIRMSG = (ARGV[0].encode('utf-8').gsub("\û", "-").gsub("ß", "a").gsub("Ú", "e").gsub("Ý", "i").gsub("¾", "o").gsub("·", "u").gsub("┐", "?"))
end
EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32')
GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32')
KILOBYTE = 1024.0
MEGABYTE = 1024.0 * 1024.0
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 ' MoveIt.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 ' MoveIt.rb "C:\" "D:\Archivo1.txt" "E:\Archivo2.jpg" "F:\Archivo3.mp3"' + "\n\n"
Process.exit
end
def bytesToUnit size1, size2
$Kilos1 = (size1 / KILOBYTE).to_s
$Megas1 = (size1 / MEGABYTE).to_s
$Kilos2 = (size2 / KILOBYTE).to_s
$Megas2 = (size2 / MEGABYTE).to_s
if ($Megas1[0]).eql? '0' or $Megas1["-"]
if ($Kilos1[0]).eql? '0'
$finalsize1 = size1.to_s + ' Bytes'
elsif
$finalsize1 = $Kilos1.split('.').first + "." + $Kilos1.split('.').last[0,1] + " Kb"
end
else
$finalsize1 = $Megas1.split('.').first + "." + $Megas1.split('.').last[0,1] + " Mb"
end # size1
if ($Megas2[0]).eql? '0' or $Megas2["-"]
if ($Kilos2[0]).eql? '0'
$finalsize2 = size2.to_s + ' Bytes'
elsif
$finalsize2 = $Kilos2.split('.').first + "." + $Kilos2.split('.').last[0,1] + " Kb"
end
else
$finalsize2 = $Megas2.split('.').first + "." + $Megas2.split('.').last[0,1] + " Mb"
end # size2
end
def date (file1, file2)
$CDate1 = (File.ctime(file1)).to_s
$CDate2 = (File.ctime(file2)).to_s
$MDate1 = (File.mtime(file1)).to_s
$MDate2 = (File.mtime(file2)).to_s
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 reintentar(source_file, dest_file)
$seguro = 'si'
if $proceso == nil
$proceso = 'DESCONOCIDO'
end # if
response = message_box("\n" +
"El proceso '" + $proceso + "' Tiene abierto el archivo: \n\n" + $archivo + "\n\n\n" +
"Reintentar?",
"Reintentar?",
BUTTONS_OKCANCEL)
if response == CLICKED_YES
Access($archivoUTF8, $DIR)
elsif response == CLICKED_NO
$no = "si"
nil
elsif response == CLICKED_CANCEL
exit
end # response
end
def moverlo()
@EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
buf = "\0" * 200
GetWindowText.call(handle, buf, 200);
if (!buf.index(param).nil?)
$seguro = 'no'
0
else
$seguro = 'si'
1
end # if
}
EnumWindows.call(@EnumWindowsProc, $archivo.split('\\').last[0..-6])
if $seguro == 'si'
FileUtils.mv $archivoUTF8, $DIR
elsif
reintentar($archivoUTF8, $DIR)
end # seguro
end
def Access(source_file, dest_file)
begin
wmi = WIN32OLE.connect("winmgmts://")
processes = wmi.ExecQuery("select * from win32_process")
for process in processes do
caption = (process.Commandline).to_s
if not caption['ruby'] and not caption['MoveIt.exe']
if caption.include? $archivo.split('\\').last[0..-6]
$proceso = process.Name
reintentar($archivoUTF8, $DIR)
end # caption.include?
end # if not ruby
$proceso = nil
end # for
if not $no == "si"
moverlo()
end # no
rescue
if File.exist?($archivoUTF8) == true
reintentar($archivoUTF8, $DIR)
end # rescue
end # begin
end
# Control de errores
if ARGV.empty? == true
help()
elsif ARGV.length < 2
help()
elsif File.directory?($DIR) == false
print "\n El directorio de destino no existe: " + $DIR + "\n"
response = message_box("\n" +
"El directorio de destino no existe: " + "\n\n" + $DIRMSG + "\n\n\n" +
"Crear el directorio?",
"Crear el directorio?",
BUTTONS_YESNO)
if response == CLICKED_YES
Dir.mkdir $DIR
elsif response == CLICKED_NO
abort
elsif response == CLICKED_CANCEL
exit
end # response
end
# Proceso
for $archivo in ARGV[1..ARGV.length].each
$archivoUTF8 = ($archivo.encode('utf-8').gsub("ß", "á").gsub("Ú", "é").gsub("Ý", "í").gsub("¾", "ó").gsub("·", "ú").gsub("┐", "\u00BF").gsub("\û", "\u2013").gsub("┤", "\u00B4").gsub("\À", "\u00B7").gsub("\¬", "\u00AA").gsub("\¼", "\u00AC").gsub("\║", "\u00BA"))
if File.exist?($archivoUTF8) == false
print "\n El archivo a mover no existe: " + $archivoUTF8 + "\n"
end # File not exist
if File.exist?($DIR + "\\" + $archivoUTF8.split('\\').last)
bytesToUnit(File.size($archivoUTF8), File.size($DIR + "\\" + $archivoUTF8.split('\\').last))
date($archivoUTF8, $DIR + "\\" + $archivoUTF8.split('\\').last)
response = message_box(
" Origen : " + $archivo.split($archivo.split('\\').last).first + "\n" +
" Archivo : " + $archivo.split('\\').last + "\n" +
" Tamano : " + $finalsize1 + "\n" +
" Creacion : " + $CDate1.split('+').first + "\n" +
" Modificacion : " + $MDate1.split('+').first + " \n\n\n" +
" Destino : " + $DIRMSG.split($archivo.split('\\').last).first + "\n" +
" Archivo : " + $archivo.split('\\').last + "\n" +
" Tamano : " + $finalsize2 + "\n" +
" Creacion : " + $CDate2.split('+').first + "\n" +
" Modificacion : " + $MDate2.split('+').first + " \n\n\n" +
" El archivo de destino ya existe. Reemplazar archivo?",
" Reemplazar archivo?",
BUTTONS_YESNO)
if response == CLICKED_YES
Access($archivoUTF8, $DIR)
elsif response == CLICKED_NO
nil
elsif response == CLICKED_CANCEL
exit
end # response
else
Access($archivoUTF8, $DIR)
end # File exist
end # for
# Fin
exit
Vaya, al final lo conseguiste! Felicidades! ;-)
He mejorado el code con lo poco que sé de Ruby :P
Si la carpeta de destino no existe, se pregunta para crearla o no. (Si no se crea, no se pueden copiar los archivos xD)
Y en fin, antes daba un error si la ruta contenia el caracter " ú ", ya lo he corregido.
Ah, Y ya no reemplaza el caracter " – ", Si el archivo contiene ese caracter (u otro ilegal) Lo copia tal cual...
Solo me falta saber como ocultar la maldita CMD (Sin usar nircmd XD o win32ole), O mejor aún, Comprobar si un archivo está abierto por algún proceso sin usar la CMD, sería mucho más eficaz...Cita de: EleKtro H@cker en 5 Marzo 2012, 11:00 AM
Resumiendo, Necesito una forma más nátiva y eficaz en Ruby para comprobar si un archivo está siendo usado por algún proceso:
Ejemplo:
If $archivo ABIERTO POR $cualquier_programa_de_windows
Sleep 01
elsif
mover $archivo a...
end
PD: Deposite su ayuda -----> [ AQUÍ (http://foro.elhacker.net/scripting/ruby_recibir_el_exitstatus_de_una_instancia_de_la_cmd_abierta_por_win32ole-t355444.0.html) ] <-----Gracias
He vuelto a modificar el script, Ahora muestra más información en esta ventana:
(http://img827.imageshack.us/img827/548/prtscrcapturezx.jpg)
No he conseguido hacer un "split" para cortar los 5 dígitos del final, Pero bueno.
Sé que es una "tool" rara, pero no por eso tiene que dejar de ser interesante (Aunque sea para aprender), Prueben y comenten xD
La sintaxis indentación y demás ccomo por ejemplo los métodos repetidos o la funcion de convertir el tamaño a MB se puede simplificar para no repetirlo, Lo sé está fatal, Es lo que tiene probar 1.000 cosas en un día y hacer 2.000 tests con cada modificación para asegurar que no haya errores...
Cuando consiga lo único que me falta para acabar este maldito code lo arreglaré todo y lo dejaré bonito xD
Salu2
He simplificado el code como he podido, bueno, digamos que le he "quitado mierd@" xD
he corregifo un fallo , no salia la pantalla de ayuda
hmmm, me faltaba por agregar unos cuantos cracteres ilegales bastante comunes en los nombres de los archivos como º ª ´, todavia me faltan 2 más, uno muy importante es la comilla ', pero no se como hacerlo, ya lo descubriré.
Y ya he arreglado la caja de dialogo para que no muestre esos últimos 5 dígitos.
Ahora sí, Ya no lo edito más hasta que encuentre ayuda para el problemón del acceso al archivo, Lo prometo (Dedos cruzados :P). Lo cierto es que lo volveré a editar si me doy cuenta de algún fallo...
Saludos...
Bueno, a esto ya se le puede llamar versión 1.0 :)
No he correjido fallos porque no hay xD
Pero ya no usa la CMD para comprobar si un archivo está abierto por algún proceso antes de moverlo :)
He retocado un poco más la info de los dialogos de texto, arriba podeis ver las imagenes (Si es que a alguien le interesa esto xD...)
saludos