Chiamare un processo Win32

Salve,

sto sviluppando un gioco con RPG Maker VX che usa internalmente Ruby
1.8.1.

Sto scrivendo uno script che avvia un processo, ad esempio notepad.exe
in modo da non bloccare il codice di esecuzione.

Il problema principale è che non posso usare “require” perchè non lo
capisce.

Qualcuno ha un’idea di come posso fare?

Qualcosa tipo Win32API.new( ‘kernel32’, “CreateProcess”, [‘L’], “n” )

e poi chiamare notepad.exe ma davvero non ho la piu pallida idea di come
si fa.

Spero qualcuno possa aiutarmi!

Prova con:
system “notepad.exe”

Marco M. wrote:

Prova con:
system “notepad.exe”

Ciao,

si avevo già provato questo metodo… il problema è che apre una pop up
della shell… ho provato con system “start /B notepad.exe” ma /B non
sembra funzionare come avrei sperato :frowning:

Marco Di antonio wrote:

Marco M. wrote:

Prova con:
system “notepad.exe”

Ciao,

si avevo già provato questo metodo… il problema è che apre una pop up
della shell… ho provato con system “start /B notepad.exe” ma /B non
sembra funzionare come avrei sperato :frowning:

A me non apre nessun popup, sono aggiornate le gemme win32?
Ocio che con start parte un nuovo processo

Prova a guardare in questo blog:

ci sono parecchi esempi

Marco M. wrote:

Marco Di antonio wrote:

Marco M. wrote:

Prova con:
system “notepad.exe”

Ciao,

si avevo già provato questo metodo… il problema è che apre una pop up
della shell… ho provato con system “start /B notepad.exe” ma /B non
sembra funzionare come avrei sperato :frowning:

A me non apre nessun popup, sono aggiornate le gemme win32?
Ocio che con start parte un nuovo processo

Non ti apre niente perchè stai avviando lo script da terminale, avvialo
fuori da terminale e vedrai :slight_smile:

2009/6/22 Marco Di antonio [email protected]

sto sviluppando un gioco con RPG Maker VX che usa internalmente Ruby
1.8.1.

1.8.1… non è un po’ vetusta come versione? :slight_smile:

Sto scrivendo uno script che avvia un processo, ad esempio notepad.exe
in modo da non bloccare il codice di esecuzione.

Parto dal presupposto che con “non bloccare il codice di esecuzione”
tu intenda che non appena notepad.exe viene lanciato, il controllo
torna allo script ruby in modo da poter proseguire con il normale
flusso dell’applicazione (cosa che di fatto esclude metodi come system
poiché “ascoltano” l’stdout del nuovo processo, bloccando di fatto lo
script ruby fino alla chiusura del processo stesso).

Detto questo, ci sarebbe win32-process che è comodissima come libreria
(richiede come dipendenza windows-pr), ma la compatibilità è data solo
da ruby 1.8.2 in poi e se effettivamente hai a disposizione solo
1.8.1…
Ad ogni modo ecco un esempio:

require ‘win32/process’

process_info = Process.create(
:app_name => “notepad.exe”,
:creation_flags => Process::DETACHED_PROCESS,
:process_inherit => false
)

Il problema principale è che non posso usare “require” perchè non lo
capisce.

Più che altro, require non c’entra con quanto vorresti ottenere.

Qualcuno ha un’idea di come posso fare?
Qualcosa tipo Win32API.new( ‘kernel32’, “CreateProcess”, [‘L’], “n” )

Più complesso (e molto più noioso) di win32-process, ma almeno non ti
porti dietro dipendenze esterne rispetto alla stdlib di ruby. Ecco un
esempio ridotto all’osso, anche nella valorizzazione dei parametri:

close_handle = Win32API.new(‘kernel32’, ‘CloseHandle’, ‘L’, ‘L’)
create_process = Win32API.new(‘kernel32’, ‘CreateProcess’, ‘PPPPLLLPPP’,
‘L’)
startup_info =
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].pack(‘LLLLLLLLLLLLSSLLLL’)
process_info = [0,0,0,0].pack(‘LLLL’)

created = create_process.call(
0, # lpApplicationName
“notepad.exe”, # lpCommandLine
0, # lpProcessAttributes
0, # lpThreadAttributes
0, # bInheritHandles
0x08, # dwCreationFlags
0, # lpEnvironment
“C:/Temp/”, # lpCurrentDirectory
startup_info, # lpStartupInfo
process_info # lpProcessInformation
)

close_handle.call(process_info[0,4].unpack(‘L’).first)
close_handle.call(process_info[4,4].unpack(‘L’).first)

Nota bene: process_info è una struttura al cui interno vengono
memorizzati gli handle del processo appena creato e del thread
principale di quest’ultimo. Essi vanno necessariamente chiusi
(certo, a meno che non ti servano in giro per la tua
applicazione/script ruby, ma dubito), pena il rimanere allocati in
memoria anche alla chiusura del processo esterno: questo ti porterebbe
inesorabilmente a leak di memoria se la tua applicazione principale
dovesse rimanere aperta per tanto tempo lanciando spesso processi
esterni. Uomo avvisato… :slight_smile:

Comunque per la valorizzazione dei parametri di CreateProcess e altre
info c’è CreateProcessA function (processthreadsapi.h) - Win32 apps | Microsoft Learn

PS: dato che non so che diavolo verrà fuori come impaginazione, i due
snippet sono anche qui win32-process.rb · GitHub

Ciao,
Daniele


Daniele A.
http://www.clorophilla.net/blog/
http://twitter.com/JoL1hAHN

grazie appena torno dal lavoro(stanotte) lo provo!

Sembra funzionare alla grande… grazie!!!

Marco Di antonio wrote:

Sembra funzionare alla grande… grazie!!!

Adesso però ce lo fai vedere questo rpg scritto in ruby???

2009/7/1 Marco M. [email protected]:

Con system “start notepad” puoi iniziare un nuovo processo in modo da
non attenderne il termine, ma aveva già provato e gli compariva una
shell, la cosa strana è che a me non compare se non quella
dell’interprete ma è normale che ci sia e comunque c’è anche con i
metodi più complessi che hai illustrato tu.

A te non compare perché esegui lo script da un interprete che gira in
una shell (istanza di cmd.exe) con una sua finestra di console. Il
comando START crea una nuova shell ereditando l’handle di una
eventuale finestra di console già esistente, lancia il processo
secondario e poi termina la shell da lui creata restituendo il
controllo. Se, come nel suo caso, il comando START viene eseguito da
un processo che non ha associato alcuna istanza di shell, allora
l’esecuzione di START comporterà la creazione di una nuova shell il
che comporta anche, tuttavia, la creazione di una nuova finestra di
console la quale si chiuderà non appena START avrà terminato di
lanciare il processo secondario.

Per la cronaca non è assolutamente detto che ruby giri per forza in
una finestra di console (es. rubyw.exe non crea un’istanza di shell
quando viene eseguito, oppure come nel caso di Marco l’engine di ruby
può essere embeddato in un’altra applicazione GUI… ed ecco perché
gli compare per un attimo una finestra di console usando START).


Daniele A.
http://www.clorophilla.net/blog/
http://twitter.com/JoL1hAHN

Marco M. wrote:

Marco Di antonio wrote:

Sembra funzionare alla grande… grazie!!!

Adesso però ce lo fai vedere questo rpg scritto in ruby???

Uscirà il primo capitolo del gioco (circa 4 ore) tra qualche giorno…
metterò il link qui :wink:

Come promesso, ecco il Capitolo del gioco :slight_smile:

http://lodestone2d.sourceforge.net

Daniele A. wrote:

Sto scrivendo uno script che avvia un processo, ad esempio notepad.exe
in modo da non bloccare il codice di esecuzione.

Parto dal presupposto che con “non bloccare il codice di esecuzione”
tu intenda che non appena notepad.exe viene lanciato, il controllo
torna allo script ruby in modo da poter proseguire con il normale
flusso dell’applicazione (cosa che di fatto esclude metodi come system
poich� “ascoltano” l’stdout del nuovo processo, bloccando di fatto lo
script ruby fino alla chiusura del processo stesso).

Con system “start notepad” puoi iniziare un nuovo processo in modo da
non attenderne il termine, ma aveva già provato e gli compariva una
shell, la cosa strana è che a me non compare se non quella
dell’interprete ma è normale che ci sia e comunque c’è anche con i
metodi più complessi che hai illustrato tu.