PDA

View Full Version : [Java] Controllare lo sportellino cd


agente mm8
08-11-2008, 21:21
E' possibile in java aprire e chiudere lo sportellino del pc? Come?

frizzo28
09-11-2008, 15:22
Da quanto ho visto su internet direttamente da java e' difficile. Il metodo consigliato e' di richiamare tramite il java un file exe cmq io ho risolto con questo script VBS di Giovanni Cenati cosi' modificato

'*****************************************************
' eject.vbs
' Cenati Giovanni - http://digilander.libero.it/Cenati
' Codice liberamente utilizzabile citando il sito
' Questo script trova tutti i lettori cd collegati
' al pc e li espelle.
'*****************************************************
Set oWMP = CreateObject("WMPlayer.OCX.7")

Set colCDROMs = oWMP.cdromCollection
'Chiede a MediaPlayer l'elenco dei drive cdrom
'oppure posso specificarne la lettera come qui sotto.
'Set oCD = oWMP.cdromCollection.getByDriveSpecifier("e:")
'oCD.Eject

if colCDROMs.Count > 0 then
for i=0 to colCDROMs.Count - 1
'Chiede a MediaPlayer la lettera dell'i-esimo drive cdrom
strDrive= oWMP.cdromCollection.item(i).driveSpecifier

colCDROMs.Item(i).Eject

next 'drive nella collezione dei drive CDROM
end if
wscript.quit


E questo codice java che non fa altro che eseguire il file VBS di nome apri.vbs

class Apri
{
public static void main(String args[])
{
try{
Runtime r = Runtime.getRuntime();
Process proc=r.exec("cmd /c apri.vbs");
}
catch(Exception e){}
}
}


P.S. testato su Vista Ultimate e funziona... credo funzioni anche su winzozz XP su 98 mi sa di no... forse per farlo andare su 98 bisognerebbe modificare
Process proc=r.exec("cmd /c apri.vbs");
in
Process proc=r.exec("command /c apri.vbs");
ma non ne sono sicuro...

ciao

agente mm8
09-11-2008, 16:13
Grazie 1000 che non sono pratico di vbs, devo avere qualche libreria particolare installata sul PC?
Esiste un comando per far chiudere lo sportellino, oltre che ad aprirlo?
Che so, una cosa tipo:
'ocd.Close
Boh...
E poi devo fare, in java:
Runtime.getRuntime().exec("cmd /C sportello.vbs");
oppure
Runtime.getRuntime().exec("cmd /C start sportello.vbs");
???
Grazie 1000

frizzo28
09-11-2008, 17:47
Per richiudere ...

'*****************************************************
' eject.vbs
' Cenati Giovanni - http://digilander.libero.it/Cenati
' Codice liberamente utilizzabile citando il sito
' Questo script trova tutti i lettori cd collegati
' al pc e li espelle.
'*****************************************************
Set oWMP = CreateObject("WMPlayer.OCX.7")

Set colCDROMs = oWMP.cdromCollection
'Chiede a MediaPlayer l'elenco dei drive cdrom
'oppure posso specificarne la lettera come qui sotto.
'Set oCD = oWMP.cdromCollection.getByDriveSpecifier("e:")
'oCD.Eject

if colCDROMs.Count > 0 then
for i=0 to colCDROMs.Count - 1
'Chiede a MediaPlayer la lettera dell'i-esimo drive cdrom
strDrive= oWMP.cdromCollection.item(i).driveSpecifier

colCDROMs.Item(i).Eject
colCDROMs.Item(i).Eject
next 'drive nella collezione dei drive CDROM
end if
wscript.quit
Basta ripetere 2 volte il comando per aprire(in grassetto quello che ho aggiunto)...
Pero' e' da migliorare queto codice... perche' se i lettori sono aperti e poi usi questo per chiudere tutto ok ma se sono chiusi ed esegui il file per chiuderli i lettori vengono aperti e richiusi... cmq questo e' un problema che puoi risolvere tramite VBS facendo un controllo se il lettore e' aperto o meno..
ciao :)

agente mm8
09-11-2008, 19:19
Grazie mille per l'interessamento, ma ho ancora un dubbio:
Grazie 1000 che non sono pratico di vbs, devo avere qualche libreria particolare installata sul PC?

Se sì, c'è un modo per farle scaricare e installare direttamente dal mio programma?

frizzo28
11-11-2008, 15:38
Grazie mille per l'interessamento, ma ho ancora un dubbio:

Se sì, c'è un modo per farle scaricare e installare direttamente dal mio programma?

Non mi risulta serva nulla di particolare praticamente tutti i sistemi winzozz hanno l'occorrente per eseguire i VBS (Vista,XP di sicuro gli altri nn so... ma credo di si...)

Ricordati pero'
P.S. testato su Vista Ultimate e funziona... credo funzioni anche su winzozz XP su 98 mi sa di no... forse per farlo andare su 98 bisognerebbe modificare
Process proc=r.exec("cmd /c apri.vbs");
in
Process proc=r.exec("command /c apri.vbs");
ma non ne sono sicuro...
ciao

agente mm8
11-11-2008, 16:05
Ok, per me l'importante è che funzioni su XP.
Thanks!:D

DanieleC88
12-11-2008, 02:03
Funzionerà pure, ma come metodo è orripilante! :asd:
Io ti consiglio (visto che la portabilità dici non essere un problema) di interfacciarti tramite JNI a del codice C/C++ che invoca le API Win32 per l'occasione. Ci vuole un po' più di lavoro forse ma è sicuramente un metodo più pulito.

agente mm8
12-11-2008, 12:24
Funzionerà pure, ma come metodo è orripilante! :asd:
Io ti consiglio (visto che la portabilità dici non essere un problema) di interfacciarti tramite JNI a del codice C/C++ che invoca le API Win32 per l'occasione. Ci vuole un po' più di lavoro forse ma è sicuramente un metodo più pulito.

Ok, ci proverò...peccato però che conosca solo Java, Visual Basic e Javascript...

DanieleC88
12-11-2008, 13:48
Tranquillo, ci vogliono due righe di C, non devi nemmeno conoscerlo il linguaggio. ;)

fero86
12-11-2008, 16:41
Il metodo consigliato e' di richiamare tramite il java un file exe il metodo consigliato non è Java :D


cmq io ho risolto con questo script VBS di Giovanni Cenati cosi' modificato ... chi?? :D


Funzionerà pure, ma come metodo è orripilante! :asd: stavo per dire :asd:


Io ti consiglio (visto che la portabilità dici non essere un problema) di interfacciarti tramite JNI a del codice C/C++ che invoca le API Win32 per l'occasione. visto che è disposto ad usare Visual Basic io Java lo eviterei del tutto. l'API da importare per l'occasione è DeviceIoControl (http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx).

frizzo28
12-11-2008, 21:09
il metodo consigliato non è Java :D
Su questo siamo d'accordo ma visto che l'utente ha richiesto esplicitamente come farlo con il java ho cercato di dargli una mano...


... chi?? :D
Ho citato l'autore... visto che lo script non l'ho fatto io... ma l'ho trovato su internet

stavo per dire :asd:

Su questo non c'e' dubbio sicuramente ce sara' un metodo migliore pe farlo...


visto che è disposto ad usare Visual Basic io Java lo eviterei del tutto. l'API da importare per l'occasione è DeviceIoControl (http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx).
Come sopra se l'utente ha richiesto di fare questa cosa dal JAVA immaggino che glie' servira' in java..

DanieleC88
12-11-2008, 21:19
Come sopra se l'utente ha richiesto di fare questa cosa dal JAVA immaggino che glie' servira' in java..
http://it.wikipedia.org/wiki/Java_Native_Interface

agente mm8
13-11-2008, 12:45
se l'utente ha richiesto di fare questa cosa dal JAVA immaggino che glie' servira' in java..
infatti...

DanieleC88
13-11-2008, 12:54
infatti...
E il problema dov'è? Meglio usare VBScript? :asd:

frizzo28
13-11-2008, 14:07
@DanieleC88 Ho capito tu cosa intendi... scrivere una DLL in C e poi eseguirla tramite JNI che fa da interfaccia tra i 2 linguaggi... cosi' la soluzione sara' sicuramente migliore di VBscript che e' la prima che mi e' venuta in mente...
Ora mi sto studiando come funziona JNI se riesco posto il codice C e JAVA...:D

Questa mia frase
Come sopra se l'utente ha richiesto di fare questa cosa dal JAVA immaggino che glie' servira' in java..
era riferita a fero86 che diceva di fare direttamente tutto in Visual Basic...
Ciao:)

DanieleC88
13-11-2008, 17:57
@DanieleC88 Ho capito tu cosa intendi... scrivere una DLL in C e poi eseguirla tramite JNI che fa da interfaccia tra i 2 linguaggi...
Sì, e fidati che ci vuole più a dirlo che a farlo. E poi se vuole portare il suo programma su Linux gli basta cambiare quelle due righe di codice e ricompilarle, il resto in Java resterà intatto e il programma continuerà a funzionare completamente (aprendo e chiudendo sportellini a volontà :p).

ciao ;)

frizzo28
13-11-2008, 21:07
Fatto... ecco il codice della DLL in c(compilato con da me con dev c++)
#include <windows.h>
#include "Esempio.h"

JNIEXPORT void JNICALL Java_Esempio_Apri
(JNIEnv *env, jobject obj) {
mciSendString("Set cdaudio door open wait",NULL,0,0);
}


JNIEXPORT void JNICALL Java_Esempio_Chiudi
(JNIEnv *env, jobject obj) {
mciSendString("Set cdaudio door closed",NULL,0,0);
}

BOOL APIENTRY DllMain (
HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this is being called. */ ,
LPVOID reserved /* Not used. */ ) {

switch (reason)
{
case DLL_PROCESS_ATTACH:
break;

case DLL_PROCESS_DETACH:
break;

case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;
}

/* Returns TRUE on success, FALSE on failure */
return TRUE;
}

Il codice JAVA
public class Esempio {

public native void Apri();
public native void Chiudi();
public static void main(String[] args) {
Esempio ese = new Esempio();

ese.Apri();

//Una semplice pausa di 2 secondi del programma
try
{
Thread.sleep(2000);
}catch(InterruptedException e){}

ese.Chiudi();
}
static {
System.loadLibrary("mylib");
}
}
Mentre il file Esempio.h e' quello generato dal java...
@DanieleC88 o chiunque altro :)Domanda sul codice C: Funziona pero' in caso di + di un lettore CD questo codice apre solo uno sportellino cosa ci si puo inventare per fare una cosa ricorsiva che cerchi tutti i lettori e li apra??

DanieleC88
13-11-2008, 22:59
Sono anni che non metto mano alle API di Windows, ma mi pare di ricordare ci fosse un metodo più semplice... comunque: http://support.microsoft.com/kb/305184

Fatto questo, con DeviceIoControl() si può controllare l'espulsione dei vari sportellini.

ciao ;)