[RUBY] (APORTE) MoveIt (Complemento para el menú SendTo de Windows)

Iniciado por Eleкtro, 4 Marzo 2012, 15:25 PM

0 Miembros y 1 Visitante están viendo este tema.

Eleкtro

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.





2º Abrir las propiedades del aceso directo.




3º Añadir la ruta de este script a la propiedad "Destino".



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)







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)



Si el archivo de destino ya existe, Se pregunta por su reemplazamiento.



Si el archivo está siendo usado por el sistema, Se da lugar a reintentar o cancelar la operación.



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:





El script compilado (No muestra la consola):

EDITADO: 07/03/2012

http://www.mediafire.com/?clyzd39xxlxzn0d



El script:

EDITADO: 07/03/2012


Código (RUBY) [Seleccionar]
# -*- 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








WaAYa HaCK

La cacatúa yoyó es nueva en el zoo!

Eleкtro

#2
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:
Código (ruby) [Seleccionar]
If $archivo ABIERTO POR $cualquier_programa_de_windows
Sleep 01
elsif
mover $archivo a...
end

PD: Deposite su ayuda ----->   [     AQUÍ     ]  <-----

Gracias








Eleкtro

He vuelto a modificar el script, Ahora muestra más información en esta ventana:



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








Eleкtro

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...








Eleкtro

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