elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  (solucionado) [Ruby] Comprobar si un archivo está abierto por un proceso ???
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: (solucionado) [Ruby] Comprobar si un archivo está abierto por un proceso ???  (Leído 7,851 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
(solucionado) [Ruby] Comprobar si un archivo está abierto por un proceso ???
« en: 4 Marzo 2012, 15:31 pm »

Hola amigos

A ver, se abrir una instancia de la CMD de 3 maneras y se recibir el código de salida

Código
  1. puts %x[Tasklist /v | Find "%tmp:~0,30%" >NUL]
  2. response = $?.exitstatus

Eso me funciona.

Pero ahora necesito abrir la consola en modo oculto (Y solo se hacerlo con el modulo Win32ole), y entonces el exitstatus me manda error , no se porque:(:

Código
  1. require 'win32ole'
  2. shell = WIN32OLE.new('Shell.Application')
  3.  
  4. shell.ShellExecute('CMD', '/K Tasklist /v | Find "%tmp:~0,30%" >NUL', '', '', 0)
  5. response = $?.exitstatus
  6. if response == 0
  7.  puts "hola"
  8.  end

Código:
undefined method `exitstatus' for nil:NilClass (NoMethodError)


EDITO: Esto tampoco me funciona:

Código
  1. require 'win32ole'
  2. $shell = WIN32OLE.new('Shell.Application')
  3. $shell.ShellExecute('CMD', '/c echo aaaa & pause', '', '', 1)
  4. $!.is_a?(win32ole)
  5. puts $!.exited?

Código:
`is_a?': class or module required (TypeError)

EDITO2: esto támpoco xD

Código
  1. require 'win32ole'
  2. $shell = WIN32OLE.new('Shell.Application')
  3. output = $shell.ShellExecute('CMD', '/c echo aaaa & echo %errorlevel%', '', '', 1)
  4. p output

(El caso es que con "system" si funciona  :-( )


« Última modificación: 6 Marzo 2012, 22:52 pm por EleKtro H@cker » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: [RUBY] Recibir el "exitstatus" de una instancia de la CMD abierta por Win32ole?
« Respuesta #1 en: 4 Marzo 2012, 23:32 pm »

A ver...

Después de tirarme horas leyendo documentación sobre Ruby, he llegado a una conclusion, Aunque no se si es posible...

"Unless" funciona como: "A menos que..."

Y yo busco un operador que funcione así:

"Hasta que..."


Vale perdón, no sabia la traducción al ingles xD


Me estoy haciendo un lio tremendo, alguien me ayuda a arreglar esto?:

Código:
until...


EDITO:

Ya lo he arreglado, Pero me he dado cuenta de que no me sirve para el propósito...

until file.readable?  comprueba exactamente el archivo, Pero va demasiado rápido y, osea, cuando lo comprueba, no hay datos escritos todavía en el archivo, está vacío
y por eso: puts File.zero? siempre es "true" , A menos que ponga un "sleep 1.0"  entre until y puts... y así le doy tiempo a que el comando de la CMD escriba los datos en el archivo...  

Nada, no me sirve, depende mucho de la velocidad de un PC.

Necesito alguna manera más práctica para recibir el código de salida, bueno, el "exitsatatus" de la instancia de la CMD lanzada con win32ole





De todas formas aqui dejo esto...

Código
  1. def Access(source_file, dest_file)
  2. ENV['tmp'] = $archivo.split('\\').last.split('.').first
  3. 'cheat environment_variables --add'
  4.  
  5. $shell.ShellExecute('CMD', '/C Tasklist /v | Find "%tmp:~10%">c:/Windows/temp/moveitexitcode.txt', '', '', 0)
  6.  
  7. until File.exist?('c:\Windows\temp\moveitexitcode.txt').eql? true
  8. end
  9. puts File.zero?('c:\Windows\temp\moveitexitcode.txt')
  10.  
  11.  if File.zero?('c:\Windows\temp\moveitexitcode.txt').eql? false
  12.  
  13.     reintentar($archivo.encode('utf-8').gsub("", "-"), ARGV[0])
  14. end
  15.  
  16.   if File.zero?('c:\Windows\temp\moveitexitcode.txt').eql? true
  17.     FileUtils.mv $archivo.encode('utf-8').gsub("", "-"), ARGV[0]
  18.  end
  19.  
  20.  
  21. begin
  22. File.delete('c:\Windows\temp\moveitexitcode.txt')
  23. rescue Errno::EACCES
  24. retry
  25. end
  26. end


« Última modificación: 5 Marzo 2012, 00:15 am por EleKtro H@cker » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: [RUBY] Recibir el "exitstatus" de una instancia de la CMD abierta por Win32ole?
« Respuesta #2 en: 5 Marzo 2012, 11:00 am »

Definitivamente el método de "comprobar el exitstatus" no me sirve para nada, engaña mucho, Por ejemplo he echo comprobaciones y el Winamp tarda 10 segundos en actualizarse en el "tasklist" (o al revés, el tasklist será el q tarda 10 segundos, no se)...

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
  1. If $archivo ABIERTO POR $cualquier_programa_de_windows
  2. Sleep 01
  3. elsif
  4. mover $archivo a...
  5. end





Aqui dejo esto, lo siento por tanto borrador xD


Código
  1. def Access(source_file, dest_file)
  2. begin
  3.  ENV['tmp'] = $archivo.split('\\').last.split('.').first
  4.  'cheat environment_variables --add'
  5.  
  6.  # CÓDIGO ORIGINAL:
  7.  # system('start /b /MIN cmd /C Tasklist /v | Find "%tmp:~10%" >NUL')
  8.  # ESTA PARTE HAY QUE MEJORARLA PARA QUE NO SE VEA LA CONSOLA
  9.  
  10.   system('Title MOVEMEBYELEKTRO & NirCMD win hide ititle "MOVEMEBYELEKTRO" & Tasklist /v | Find "%tmp:~10%" >NUL')
  11.  
  12. until $?.exitstatus.eql? 1 or $?.exitstatus.eql? 0
  13.    sleep 0.1
  14. end
  15.  
  16.   if $?.exitstatus.eql? 0
  17.      reintentar($archivo.encode('utf-8').gsub("", "-"), ARGV[0])
  18.   end
  19.  
  20.   if $?.exitstatus.eql? 1
  21.      FileUtils.mv $archivo.encode('utf-8').gsub("", "-"), ARGV[0]
  22.   end
  23.  
  24. rescue
  25.   reintentar($archivo.encode('utf-8').gsub("", "-"), ARGV[0])
  26. end
  27. end
« Última modificación: 5 Marzo 2012, 11:06 am por EleKtro H@cker » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: [RUBY] Recibir el "exitstatus" de una instancia de la CMD abierta por Win32ole?
« Respuesta #3 en: 6 Marzo 2012, 16:55 pm »

Por fin he encontrado algo útil!!!

Lo malo es que el ejemplo es para Delphi...
Citar
Using the Native API function NtQuerySystemInformation you can list all open handles from all processes
http://stackoverflow.com/questions/1575286/delphi-get-what-files-are-opened-by-an-application

API: Win32API
Función: NtQuerySystemInformation
http://msdn.microsoft.com/en-us/library/ms724509%28VS.85%29.aspx


¿Alguien podria ayudarme a entender como utilizarla para averiguar lo que necesito, en ruby?


EDITO:

He encontrado un ejemplo en chino, pero no hace lo que necesito ,lo único que he encontrado:


Código
  1. #!/usr/local/bin/ruby
  2.  
  3. # WindowsNTŒn‚ÅCPU•‰‰×‚ƃƒ‚ƒŠ•‰‰×‚ð‹L˜^‚·‚é
  4.  
  5. require "Win32API"
  6.  
  7. # ’²¸ŠÔŠu[•b]
  8. interval = 1
  9.  
  10. # CPU •‰‰×‚̎擾—p
  11. NtQuerySystemInformation = Win32API.new('NTDLL', 'NtQuerySystemInformation', 'LPLP', 'I')
  12. perfInfo = "\0\0\0\0" * 78
  13. timeInfo = "\0\0\0\0" * 8
  14. sysInfoLen = "\0\0\0\0"
  15.  
  16. # ƒƒ‚ƒŠÁ”ï‚̎擾—p
  17. GlobalMemoryStatus = Win32API.new('kernel32','GlobalMemoryStatus','P','V')
  18. memStruct = "\0\0\0\0" * 8
  19.  
  20. $regular = false
  21. $formerIdle = 0
  22. $formerTime = 0
  23. while true
  24.  # ƒAƒCƒhƒ‹ŽžŠÔ‚̎擾
  25.  NtQuerySystemInformation.call(2, perfInfo, perfInfo.size, sysInfoLen)
  26.  idle = perfInfo.unpack("L")[0]
  27.  # ƒVƒXƒeƒ€ŽžŠÔ‚̎擾
  28.  NtQuerySystemInformation.call(3, timeInfo, timeInfo.size, sysInfoLen)
  29.  time = timeInfo.unpack("L3")[2]
  30.  # ·•ª‚Å CPU •‰‰×‚ðŒvŽZ[%]
  31.  cpuLoad = 100.0 - ((100.0 * (idle - $formerIdle)) / (time - $formerTime))
  32.  if cpuLoad < 0 or cpuLoad > 100
  33.    $regular = false
  34.  end
  35.  $formerIdle = idle
  36.  $formerTime = time
  37.  
  38.  # ƒƒ‚ƒŠÁ”ï‚̎擾[%]
  39.  GlobalMemoryStatus.call(memStruct)
  40.  memLoad =memStruct.unpack("L2")[1]
  41.  
  42.  if $regular
  43.    printf "time=%s cpu=%4.1f mem=%4.1f\n", \
  44.      Time.now.strftime("%H:%M:%S"), cpuLoad, memLoad
  45.  else
  46.    $regular = true
  47.  end
  48.  
  49.  sleep interval
  50. end
« Última modificación: 6 Marzo 2012, 17:02 pm por EleKtro H@cker » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: [Ruby] Comprobar si un archivo está siendo usado ??? NtQuerySystemInformation
« Respuesta #4 en: 6 Marzo 2012, 18:28 pm »

Acabo de intentarlo usando win32ole, pero no hay nada que muestre el archivo que tiene abierto el proceso:

Lo más parecido es el:
Código:
puts process.CommandLine
Pero no es lo mismo...
 :-( :-( :-(


Código
  1. require 'win32ole'
  2.  
  3. wmi = WIN32OLE.connect("winmgmts://")
  4. processes = wmi.ExecQuery("select * from win32_process")
  5. for process in processes do
  6. puts process.Caption
  7. puts process.CommandLine
  8. puts process.CreationClassName
  9. puts process.CreationDate
  10. puts process.CSCreationClassName
  11. puts process.CSName
  12. puts process.Description
  13. puts process.ExecutablePath
  14. puts process.ExecutionState
  15. puts process.Handle
  16. puts process.HandleCount
  17. puts process.InstallDate
  18. puts process.KernelModeTime
  19. puts process.MaximumWorkingSetSize
  20. puts process.MinimumWorkingSetSize
  21. puts process.Name
  22. puts process.OSCreationClassName
  23. puts process.OSName
  24. puts process.OtherOperationCount
  25. puts process.OtherTransferCount
  26. puts process.PageFaults
  27. puts process.PageFileUsage
  28. puts process.ParentProcessId
  29. puts process.PeakPageFileUsage
  30. puts process.PeakVirtualSize
  31. puts process.PeakWorkingSetSize
  32. puts process.Priority
  33. puts process.PrivatePageCount
  34. puts process.ProcessId
  35. puts process.QuotaNonPagedPoolUsage
  36. puts process.QuotaPagedPoolUsage
  37. puts process.QuotaPeakNonPagedPoolUsage
  38. puts process.QuotaPeakPagedPoolUsage
  39. puts process.ReadOperationCount
  40. puts process.ReadTransferCount
  41. puts process.SessionId
  42. puts process.Status
  43. puts process.TerminationDate
  44. puts process.ThreadCount
  45. puts process.UserModeTime
  46. puts process.VirtualSize
  47. puts process.WindowsVersion
  48. puts process.WorkingSetSize
  49. puts process.WriteOperationCount
  50. puts process.WriteTransferCount
  51. end


EDITO:

Vale, Si, Si que me sirve:

Código
  1. wmi = WIN32OLE.connect("winmgmts://")
  2. processes = wmi.ExecQuery("select * from win32_process")
  3. for process in processes do
  4. puts process.CommandLine
  5. end

Pero no es del todo eficiente en algunos casos, Así que necesito además de esa comprobación, una segunda comprobación para comprobar el nombre de la ventana del programa, he encontrado un code que lo hace pero es para VBS creo...

Una ayuda para "Convertirlo" a Ruby? Lo he intentado pero no lo consigo:

Código
  1. On Error Resume Next
  2. strComputer = "."
  3. Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
  4. Set colItems = objWMIService.ExecQuery("Select * from Win32_ProcessStartup",,48)
  5. For Each objItem in colItems
  6.    Wscript.Echo "ShowWindow: " & objItem.ShowWindow
  7.    Wscript.Echo "Title: " & objItem.Title
  8. Next





Código
  1. require 'win32ole'
  2.  
  3. wmi = WIN32OLE.connect("winmgmts://")
  4. processes = wmi.ExecQuery("Select * from Win32_ProcessStartup")
  5. for process in processes do
  6. puts process.ShowWindow
  7. puts process.Title
  8. end

No me muestra nada, Pero támpoco da error   :(

¿Que me falta?
« Última modificación: 6 Marzo 2012, 19:06 pm por EleKtro H@cker » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: [Ruby] Comprobar si un archivo está siendo usado ??? NtQuerySystemInformation
« Respuesta #5 en: 6 Marzo 2012, 19:48 pm »

He encontrado otro script (Chino...) pero es demasiadooo avanzado para mi, no se como utilizarlo

Creo que sirve para buscar el titulo de la ventana de un proceso

Una ayuda???


Código
  1. require 'Win32API'
  2. class Wnd
  3. #for GetWindow
  4. =begin
  5. GW_CHILD=
  6. GW_OWNER=
  7. GW_HWNDFIRST=
  8. GW_HWNDNEXT=
  9. #for GetNextWindow
  10. GW_HWNDNEXT=
  11. GW_HWNDPREV=
  12. =end
  13.  
  14. def initialize
  15.    @hw = nil
  16.    @GetWindow = Win32API.new("user32","GetWindow",['L']*2,'L')
  17.    #top child
  18.    @GetTopWindow = Win32API.new("user32","GetTopWindow",['L'],'L')
  19.    # @GetNextWindow = Win32API.new("user32","GetNextWindowA",['L']*2,'L')
  20.    @GetActiveWindow = Win32API.new("user32","GetActiveWindow",[],'L')
  21.    @GetDesktopWindow = Win32API.new("user32","GetDesktopWindow",[],'L')
  22. @FindWindow=Win32API.new("user32","FindWindowA",['L','P'],'L')
  23.    @SetForegroundWindow=Win32API.new("user32","SetForegroundWindow",['L'],'V')
  24.    @GetWindowText = Win32API.new("user32","GetWindowText",['L','P','i'],'i')
  25.  
  26. end
  27. def find(cap)
  28.    @hw = @FindWindow.Call(0,cap)
  29. end
  30. def fg
  31.    @SetForegroundWindow.Call(@hw)
  32. end
  33. def caption
  34.    lpString="\0"*251
  35.    len = @GetWindowText.Call(@hw,lpString,250)
  36.    p len
  37.    lpString[0,len]
  38. end
  39. def test
  40.  
  41. end
  42. end
  43.  
  44. wnd1=Wnd.new
  45. wnd1.find("Win32 SDK Reference Help")
  46. wnd1.fg
  47. puts wnd1.caption
  48. __END__




EDITO:

He conseguido sacar el título de la consola de windows , la CMD:

Código
  1. require 'Win32API'
  2.  
  3.  b = Win32API.new('kernel32' , 'GetConsoleWindow' , [] , 'L').call
  4.  title = ' '*100
  5.  win = Win32API.new('user32', 'GetWindowText', ['L', 'P', 'I'], 'I').Call(b, title, 256)
  6.  
  7. puts title


Pero ni idea de como hacerlo para todos los processos abiertos....

Quisiera algo así:

Código
  1. require 'Win32API'
  2.  
  3.  b = Win32API.new('kernel32' , 'Get ALL WINDOWS' , [] , 'L').call
  4.  title = ' '*100
  5.  
  6. if title.include? "archivo abierto"
  7.   abort
  8. end
« Última modificación: 6 Marzo 2012, 20:08 pm por EleKtro H@cker » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: (solucionado) [Ruby] Comprobar si un archivo está abierto por un proceso ???
« Respuesta #6 en: 6 Marzo 2012, 22:53 pm »

Al final la insistencia y el esfuerzo dan sus frutos

Código
  1. require 'win32/api'
  2. include Win32
  3.  
  4. # Callback example - Enumerate windows
  5. EnumWindows     = API.new('EnumWindows', 'KP', 'L', 'user32')
  6. GetWindowText   = API.new('GetWindowText', 'LPI', 'I', 'user32')
  7. EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
  8.  buf = "\0" * 200
  9.  GetWindowText.call(handle, buf, 200);
  10.  
  11.  if (!buf.index(param).nil?)
  12.    puts "window was found: handle #{handle}"
  13.    0 # stop looking after we find it
  14.  else
  15.    1
  16.  end
  17. }
  18.  
  19. EnumWindows.call(EnumWindowsProc, ' AQUI VA EL TITULO ')

Saludosss

PD: ¿Alguien lee mis problemas con Ruby? xD  :-(
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines