Programmatically close optical drive tray I really liked the close tray program that CD-ROM drivers programs used to include in MS-DOS days.
Since I live in a place where even getting an internship is impossible, I've decided to learn by myself.
I implemented this &quot;Hello World&quot; C# script to do that with a twist.
It will check the optical drive status and if open, it will close it, otherwise it will tell you that a disk is present.
Note, I went through Stack Overflow and couldn't find a way to programmatically find if the tray is open.
Another note, it will not close the tray on most laptops where such mechanism does not exist.
And finally, I used an online code beautifier for indentation.
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Management;

class Program { 
[DllImport(&quot;winmm.dll&quot;)] protected static extern int mciSendString(string Cmd, StringBuilder StrReturn, int ReturnLength, IntPtr HwndCallback);

  static void Main(string[] args) {

  ManagementObjectSearcher searcher = new ManagementObjectSearcher(&quot;SELECT MediaLoaded FROM Win32_CDROMDrive&quot;);
  ManagementObjectCollection moc = searcher.Get();
  var enumerator = moc.GetEnumerator();
  if (!enumerator.MoveNext()) throw new Exception(&quot;No elements&quot;);
  ManagementObject obj = (ManagementObject) enumerator.Current;
  bool status = (bool) obj[&quot;MediaLoaded&quot;];

  if (!status) {
    MessageBox.Show(&quot;The drive is either open or empty&quot;, &quot;Optical Drive Status&quot;);
    mciSendString(&quot;set cdaudio door closed&quot;, null, 0, IntPtr.Zero);
  }
  else MessageBox.Show(&quot;The drive is closed and contains an optical media&quot;, &quot;Optical Drive Status&quot;);
 }
}
Note that the Visual Studio C# code editor has an integrated code beautifier. Depending on your setup, it can be executed with different shortcut keys. Call it from the menu for the first time, so that you can see the active shortcut keys (it is Ctrl-E-D for me). Menu: Edit &gt; Advanced &gt; Format Document.
By using a technique called LINQ (Language INtegrated  Query), you can get the management object easier. It uses extension methods from the namespace System.Linq. Therefore, you must include a using System.Linq; at the top of your code. Then you can query with
ManagementObject managementObject = moc.FirstOrDefault();
if (managementObject == null) {
     // Handle error (output text or throw exception)
     Console.WriteLine(&quot;Could not find a management object!&quot;);
} else {
     ...
}

This FirstOrDefault extension method calls GetEnumerator and MoveNext internally and returns null if no object is available.
Do not give it the name obj. Almost everything is an object, so this name is not very informative.
Exceptions are a complex matter. It raises a lot of questions like &quot;should I throw an exception or output a message to the user?&quot;, &quot;should I create my own exception types?&quot;, &quot;should I log the exception?&quot; etc., etc. There is no single best answer to these questions. Therefore, I content myself with giving you a link: C# Exception Handling Best Practices.
If you intend to reuse this functionality, you could encapsulate it into your own class:
public enum OperationResult
{
    Failure,
    NoDriveFound,
    DriveIsOpenOrEmpty,
    MediaIsLoaded
}

public class OpticalDriveCloser
{
    public OperationResult CloseFirst()
    {
        ...
    }

    public OperationResult[] CloseAll()
    {
        ...
    }
}

It returns an operation status as enumeration type and lets the calling application decide how to proceed. I.e. it does neither call Console.WriteLine nor throw exceptions and focuses on pure, non-UI logic. A console application will have a different UI-logic than a windows forms application or a web application.