2009-09-19 4 views
4

Y a-t-il un moyen de le faire? Je sais qu'il est possible d'éjecter/de retirer par programmation le lecteur cd SOMEHOW, parce que Roxio le fait quand il me demande d'insérer un disque.Ejection et retrait programmés du lecteur de CD dans vb.net ou C#

Soit C# ou vb.net est préférable, mais c et C++ sont également acceptables en dernier recours.

Je suis presque sûr qu'il y a un moyen de le faire, je ne connais tout simplement pas les méthodes à suivre.

Je comprends c'est une demande quelque peu inhabituelle, comme Google a produit absolument rien quand je cherchais les méthodes ...

Répondre

10
using System.Runtime.InteropServices; 

[DllImport("winmm.dll")] 
static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback); 

// To open the door 
mciSendString("set CDAudio door open", null, 0, IntPtr.Zero); 

// To close the door 
mciSendString("set CDAudio door closed", null, 0, IntPtr.Zero); 

http://www.geekpedia.com/tutorial174_Opening-and-closing-the-CD-tray-in-.NET.html

+0

Travailler parfois. Pas à chaque fois. La solution alternative est plus fiable pour moi. Mais assurez-vous de lire le commentaire et d'utiliser FILE_SHARE_READ et FILE_SHARE_WRITE. – Filimindji

10

est ici une solution alternative à l'accepter un, converti d'un VB.NET sample:

using System; 
using System.IO; 
using System.Runtime.InteropServices; 

class Test 
{ 
    const int OPEN_EXISTING = 3; 
    const uint GENERIC_READ = 0x80000000; 
    const uint GENERIC_WRITE = 0x40000000; 
    const uint IOCTL_STORAGE_EJECT_MEDIA = 2967560; 

    [DllImport("kernel32")] 
    private static extern IntPtr CreateFile 
     (string filename, uint desiredAccess, 
     uint shareMode, IntPtr securityAttributes, 
     int creationDisposition, int flagsAndAttributes, 
     IntPtr templateFile); 

    [DllImport("kernel32")] 
    private static extern int DeviceIoControl 
     (IntPtr deviceHandle, uint ioControlCode, 
     IntPtr inBuffer, int inBufferSize, 
     IntPtr outBuffer, int outBufferSize, 
     ref int bytesReturned, IntPtr overlapped); 

    [DllImport("kernel32")] 
    private static extern int CloseHandle(IntPtr handle); 

    static void EjectMedia(char driveLetter) 
    { 
     string path = "\\\\.\\" + driveLetter + ":"; 
     IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, 
            IntPtr.Zero, OPEN_EXISTING, 0, 
            IntPtr.Zero); 
     if ((long) handle == -1) 
     { 
      throw new IOException("Unable to open drive " + driveLetter); 
     } 
     int dummy = 0; 
     DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, 
         IntPtr.Zero, 0, ref dummy, IntPtr.Zero); 
     CloseHandle(handle); 
    } 

    static void Main() 
    { 
     EjectMedia('f'); 
    } 
} 
+0

C'est la meilleure idée. Cela suppose des choses sur le matériel. Que faire si votre matériel a un pilote spécial pour éjecter? Vous feriez mieux d'utiliser la fonction d'éjection Shell, ce qui rendra votre code plus court et plus général. –

+1

J'ai trouvé que cela fonctionne plus fiable que la réponse acceptée. Cependant, selon les docs (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363216.aspx), "Vous devez spécifier les indicateurs d'accès FILE_SHARE_READ et FILE_SHARE_WRITE lors de l'appel de CreateFile pour ouvrir un handle vers un pilote de périphérique." Je devais ajouter ceci avant que ça marche pour moi. J'ai édité votre réponse pour les inclure. – stusherwin

+0

Je suis d'accord sur FILE_SHARE_READ et FILE_SHARE_WRITE. Si ce n'est pas spécifié, tout autre processus qui tente d'accéder au lecteur en même temps provoque l'échec de CreateFile. – Filimindji

Questions connexes