Autor
|
Tema: (solucionado) [Ruby] Comprobar si un archivo está abierto por un proceso ??? (Leído 8,284 veces)
|
Eleкtro
Ex-Staff
Conectado
Mensajes: 9.878
|
Hola amigos A ver, se abrir una instancia de la CMD de 3 maneras y se recibir el código de salida puts %x[Tasklist /v | Find "%tmp:~0,30%" >NUL] 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:(: require 'win32ole' shell = WIN32OLE.new('Shell.Application') shell.ShellExecute('CMD', '/K Tasklist /v | Find "%tmp:~0,30%" >NUL', '', '', 0) response = $?.exitstatus if response == 0 puts "hola" end
undefined method `exitstatus' for nil:NilClass (NoMethodError) EDITO: Esto tampoco me funciona: require 'win32ole' $shell = WIN32OLE.new('Shell.Application') $shell.ShellExecute('CMD', '/c echo aaaa & pause', '', '', 1) $!.is_a?(win32ole) puts $!.exited?
`is_a?': class or module required (TypeError) EDITO2: esto támpoco xD require 'win32ole' $shell = WIN32OLE.new('Shell.Application') output = $shell.ShellExecute('CMD', '/c echo aaaa & echo %errorlevel%', '', '', 1) 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
Conectado
Mensajes: 9.878
|
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?: 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 win32oleDe todas formas aqui dejo esto... def Access(source_file, dest_file) ENV['tmp'] = $archivo.split('\\').last.split('.').first 'cheat environment_variables --add' $shell.ShellExecute('CMD', '/C Tasklist /v | Find "%tmp:~10%">c:/Windows/temp/moveitexitcode.txt', '', '', 0) until File.exist?('c:\Windows\temp\moveitexitcode.txt').eql? true end puts File.zero?('c:\Windows\temp\moveitexitcode.txt') if File.zero?('c:\Windows\temp\moveitexitcode.txt').eql? false reintentar($archivo.encode('utf-8').gsub("\û", "-"), ARGV[0]) end if File.zero?('c:\Windows\temp\moveitexitcode.txt').eql? true FileUtils.mv $archivo.encode('utf-8').gsub("\û", "-"), ARGV[0] end begin File.delete('c:\Windows\temp\moveitexitcode.txt') rescue Errno::EACCES retry end end
|
|
« Última modificación: 5 Marzo 2012, 00:15 am por EleKtro H@cker »
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Conectado
Mensajes: 9.878
|
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: If $archivo ABIERTO POR $cualquier_programa_de_windows Sleep 01 elsif mover $archivo a... end
Aqui dejo esto, lo siento por tanto borrador xD def Access(source_file, dest_file) begin ENV['tmp'] = $archivo.split('\\').last.split('.').first 'cheat environment_variables --add' # CÓDIGO ORIGINAL: # system('start /b /MIN cmd /C Tasklist /v | Find "%tmp:~10%" >NUL') # ESTA PARTE HAY QUE MEJORARLA PARA QUE NO SE VEA LA CONSOLA system('Title MOVEMEBYELEKTRO & NirCMD win hide ititle "MOVEMEBYELEKTRO" & Tasklist /v | Find "%tmp:~10%" >NUL') until $?.exitstatus.eql? 1 or $?.exitstatus.eql? 0 sleep 0.1 end if $?.exitstatus.eql? 0 reintentar($archivo.encode('utf-8').gsub("\û", "-"), ARGV[0]) end if $?.exitstatus.eql? 1 FileUtils.mv $archivo.encode('utf-8').gsub("\û", "-"), ARGV[0] end rescue reintentar($archivo.encode('utf-8').gsub("\û", "-"), ARGV[0]) end end
|
|
« Última modificación: 5 Marzo 2012, 11:06 am por EleKtro H@cker »
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Conectado
Mensajes: 9.878
|
Por fin he encontrado algo útil!!! Lo malo es que el ejemplo es para Delphi... 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-applicationAPI: Win32API Función: NtQuerySystemInformationhttp://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: #!/usr/local/bin/ruby # WindowsNTŒn‚ÅCPU•‰‰×‚ƃƒ‚ƒŠ•‰‰×‚ð‹L˜^‚·‚é require "Win32API" # ’²¸ŠÔŠu[•b] interval = 1 # CPU •‰‰×‚̎擾—p NtQuerySystemInformation = Win32API.new('NTDLL', 'NtQuerySystemInformation', 'LPLP', 'I') perfInfo = "\0\0\0\0" * 78 timeInfo = "\0\0\0\0" * 8 sysInfoLen = "\0\0\0\0" # ƒƒ‚ƒŠÁ”ï‚̎擾—p GlobalMemoryStatus = Win32API.new('kernel32','GlobalMemoryStatus','P','V') memStruct = "\0\0\0\0" * 8 $regular = false $formerIdle = 0 $formerTime = 0 while true # ƒAƒCƒhƒ‹ŽžŠÔ‚̎擾 NtQuerySystemInformation.call(2, perfInfo, perfInfo.size, sysInfoLen) idle = perfInfo.unpack("L")[0] # ƒVƒXƒeƒ€ŽžŠÔ‚̎擾 NtQuerySystemInformation.call(3, timeInfo, timeInfo.size, sysInfoLen) time = timeInfo.unpack("L3")[2] # ·•ª‚Å CPU •‰‰×‚ðŒvŽZ[%] cpuLoad = 100.0 - ((100.0 * (idle - $formerIdle)) / (time - $formerTime)) if cpuLoad < 0 or cpuLoad > 100 $regular = false end $formerIdle = idle $formerTime = time # ƒƒ‚ƒŠÁ”ï‚̎擾[%] GlobalMemoryStatus.call(memStruct) memLoad =memStruct.unpack("L2")[1] if $regular printf "time=%s cpu=%4.1f mem=%4.1f\n", \ Time.now.strftime("%H:%M:%S"), cpuLoad, memLoad else $regular = true end sleep interval end
|
|
« Última modificación: 6 Marzo 2012, 17:02 pm por EleKtro H@cker »
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Conectado
Mensajes: 9.878
|
Acabo de intentarlo usando win32ole, pero no hay nada que muestre el archivo que tiene abierto el proceso: Lo más parecido es el: Pero no es lo mismo... require 'win32ole' wmi = WIN32OLE.connect("winmgmts://") processes = wmi.ExecQuery("select * from win32_process") for process in processes do puts process.Caption puts process.CommandLine puts process.CreationClassName puts process.CreationDate puts process.CSCreationClassName puts process.CSName puts process.Description puts process.ExecutablePath puts process.ExecutionState puts process.Handle puts process.HandleCount puts process.InstallDate puts process.KernelModeTime puts process.MaximumWorkingSetSize puts process.MinimumWorkingSetSize puts process.Name puts process.OSCreationClassName puts process.OSName puts process.OtherOperationCount puts process.OtherTransferCount puts process.PageFaults puts process.PageFileUsage puts process.ParentProcessId puts process.PeakPageFileUsage puts process.PeakVirtualSize puts process.PeakWorkingSetSize puts process.Priority puts process.PrivatePageCount puts process.ProcessId puts process.QuotaNonPagedPoolUsage puts process.QuotaPagedPoolUsage puts process.QuotaPeakNonPagedPoolUsage puts process.QuotaPeakPagedPoolUsage puts process.ReadOperationCount puts process.ReadTransferCount puts process.SessionId puts process.Status puts process.TerminationDate puts process.ThreadCount puts process.UserModeTime puts process.VirtualSize puts process.WindowsVersion puts process.WorkingSetSize puts process.WriteOperationCount puts process.WriteTransferCount end
EDITO: Vale, Si, Si que me sirve: wmi = WIN32OLE.connect("winmgmts://") processes = wmi.ExecQuery("select * from win32_process") for process in processes do puts process.CommandLine 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: On Error Resume Next strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set colItems = objWMIService.ExecQuery("Select * from Win32_ProcessStartup",,48) For Each objItem in colItems Wscript.Echo "ShowWindow: " & objItem.ShowWindow Wscript.Echo "Title: " & objItem.Title Next
require 'win32ole' wmi = WIN32OLE.connect("winmgmts://") processes = wmi.ExecQuery("Select * from Win32_ProcessStartup") for process in processes do puts process.ShowWindow puts process.Title 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
Conectado
Mensajes: 9.878
|
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??? require 'Win32API' class Wnd #for GetWindow =begin GW_CHILD= GW_OWNER= GW_HWNDFIRST= GW_HWNDNEXT= #for GetNextWindow GW_HWNDNEXT= GW_HWNDPREV= =end def initialize @hw = nil @GetWindow = Win32API.new("user32","GetWindow",['L']*2,'L') #top child @GetTopWindow = Win32API.new("user32","GetTopWindow",['L'],'L') # @GetNextWindow = Win32API.new("user32","GetNextWindowA",['L']*2,'L') @GetActiveWindow = Win32API.new("user32","GetActiveWindow",[],'L') @GetDesktopWindow = Win32API.new("user32","GetDesktopWindow",[],'L') @FindWindow=Win32API.new("user32","FindWindowA",['L','P'],'L') @SetForegroundWindow=Win32API.new("user32","SetForegroundWindow",['L'],'V') @GetWindowText = Win32API.new("user32","GetWindowText",['L','P','i'],'i') end def find(cap) @hw = @FindWindow.Call(0,cap) end def fg @SetForegroundWindow.Call(@hw) end def caption lpString="\0"*251 len = @GetWindowText.Call(@hw,lpString,250) p len lpString[0,len] end def test end end wnd1=Wnd.new wnd1.find("Win32 SDK Reference Help") wnd1.fg puts wnd1.caption __END__
EDITO: He conseguido sacar el título de la consola de windows , la CMD: require 'Win32API' b = Win32API.new('kernel32' , 'GetConsoleWindow' , [] , 'L').call title = ' '*100 win = Win32API.new('user32', 'GetWindowText', ['L', 'P', 'I'], 'I').Call(b, title, 256) puts title
Pero ni idea de como hacerlo para todos los processos abiertos.... Quisiera algo así: require 'Win32API' b = Win32API.new('kernel32' , 'Get ALL WINDOWS' , [] , 'L').call title = ' '*100 if title.include? "archivo abierto" abort end
|
|
« Última modificación: 6 Marzo 2012, 20:08 pm por EleKtro H@cker »
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Conectado
Mensajes: 9.878
|
Al final la insistencia y el esfuerzo dan sus frutos require 'win32/api' include Win32 # Callback example - Enumerate windows EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32') GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32') EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param| buf = "\0" * 200 GetWindowText.call(handle, buf, 200); if (!buf.index(param).nil?) puts "window was found: handle #{handle}" 0 # stop looking after we find it else 1 end } EnumWindows.call(EnumWindowsProc, ' AQUI VA EL TITULO ')
Saludosss PD: ¿Alguien lee mis problemas con Ruby? xD
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Comprobar si un archivo en internet existe (SOLUCIONADO)
« 1 2 »
Programación Visual Basic
|
Littl3
|
11
|
17,838
|
14 Mayo 2008, 15:15 pm
por seba123neo
|
|
|
Saber si un proceso esta abierto.
Scripting
|
Pony-Magic
|
2
|
4,584
|
31 Diciembre 2008, 20:48 pm
por -Soldier-
|
|
|
comprobar tamaño de un archivo desde otro (batch)[Solucionado]
Scripting
|
manel92
|
6
|
12,751
|
4 Septiembre 2009, 12:14 pm
por manel92
|
|
|
API para que el programa detecte si esta abierto un proceso antes de continuar
Programación Visual Basic
|
Franqox
|
9
|
9,680
|
23 Diciembre 2010, 20:54 pm
por BlackZeroX
|
|
|
[Solucionado] Obtener código MD5 Checksum de un proceso abierto
.NET (C#, VB.NET, ASP)
|
Segurida
|
2
|
3,535
|
8 Mayo 2011, 22:24 pm
por Segurida
|
|