2008-09-12 48 views
8

有誰知道在Windows 2000或更高版本上以編程方式關閉CD托盤的方法? 打開CD托盤存在,但我似乎無法使其關閉,特別是在W2K下。Windows CDROM Eject

我特別尋找一種方法來從一個批處理文件中做到這一點,如果可能的話,但API調用是可以的。

回答

5

下面是使用Win32 API的一個簡單的方法:


[DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi)] 
     protected static extern int mciSendString(string lpstrCommand,StringBuilder lpstrReturnString,int uReturnLength,IntPtr hwndCallback); 

public void OpenCloseCD(bool Open) 
{ 
    if (Open) 
    { 
     mciSendString("set cdaudio door open", null, 0, IntPtr.Zero); 
    } 
    else 
    { 
     mciSendString("set cdaudio door closed", null, 0, IntPtr.Zero); 
    } 
} 

+1

這是如何在多驅動器系統上工作的?我沒有看到任何指定驅動器。 – OwenP 2009-12-31 19:11:18

+3

-1 mci是一種古老的(Win3.x)技術,僅適用於單個驅動器,可以進行投票。還必須安裝Windows媒體播放器?但我不確定。歐洲的'N'版本的Windows不帶有媒體播放器,所以要小心。 – unixman83 2011-04-16 11:30:47

1

Nircmd是一個非常方便的免費軟件命令行工具,提供各種選項,包括打開和關閉CD托盤。

+0

僅供參考:www.nirsoft.net被我公司封鎖,我發現這個程序。 http://spywarefiles.prevx.com/RRIDCH001610050/NIRCMD.EXE.html – kenny 2008-09-12 11:10:23

+1

閱讀這個描述並不讓我擔心 - 看起來他們很擔心Nircmd,因爲它是一個可以做事情的工具。 Sophos,Avast和ESET都無法在我的任何系統上,在家或在工作中阻止nircmd。另一方面,我從來沒有聽說過Prevx。 – 2008-09-17 19:48:58

11

我有點喜歡用DeviceIoControl的,因爲它讓我有可能彈出任何一種可移動驅動器(如USB和閃存盤作爲以及CD托盤)。大codez正確使用彈出時的DeviceIoControl(剛加入適當的錯誤處理)磁盤:

bool ejectDisk(TCHAR driveLetter) 
{ 
    TCHAR tmp[10]; 
    _stprintf(tmp, _T("\\\\.\\%c:"), driveLetter); 
    HANDLE handle = CreateFile(tmp, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 
    DWORD bytes = 0; 
    DeviceIoControl(handle, FSCTL_LOCK_VOLUME, 0, 0, 0, 0, &bytes, 0); 
    DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0, &bytes, 0); 
    DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, 0, 0, 0, 0, &bytes, 0); 
    CloseHandle(handle); 
    return true; 
} 
3

我注意到安德烈亞斯馬格努鬆的回答也不太工作作爲瀏覽器的彈出按鈕做了完全一樣的。具體來說,使用Andreas代碼的驅動器在資源管理器中未變灰,但是如果使用了Eject命令。所以我做了一些調查。

我運行API監視器時,從資源管理器(Windows 7 SP1 64位)運行彈出命令。我還發現了一個很好的MSKB文章165721,標題爲How To Ejecting Removable Media in Windows NT/Windows 2000/Windows XP。在MSKB文章的最有趣的部分是引述如下:

  1. 調用的CreateFile與GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE和OPEN_EXISTING。 lpFileName參數應該是\。\ X:(其中X是實際的驅動器號)。所有其他參數可以爲零。
  2. 通過DeviceIoControl發出FSCTL_LOCK_VOLUME IOCTL鎖定音量。如果任何其他應用程序或系統正在使用該卷,則此IOCTL將失敗。一旦這個函數成功返回,應用程序就可以保證該卷不會被系統中的其他任何東西使用。
  3. 通過發出FSCTL_DISMOUNT_VOLUME IOCTL來卸除卷。這會導致文件系統刪除有關卷的所有知識,並丟棄有關卷的所有內部信息。
  4. 確保可以通過發佈IOCTL_STORAGE_MEDIA_REMOVAL IOCTL來刪除介質。在調用此IOCTL之前,將PREVENT_MEDIA_REMOVAL結構的PreventMediaRemoval成員設置爲FALSE。這可以防止設備阻止媒體的移除。
  5. 使用IOCTL_STORAGE_EJECT_MEDIA IOCTL彈出媒體。如果設備不允許自動彈出,則可跳過IOCTL_STORAGE_EJECT_MEDIA,並指示用戶移除媒體。
  6. 關閉第一步中獲得的音量句柄或發出FSCTL_UNLOCK_VOLUME IOCTL。這允許驅動器被其他 進程使用。

安德烈亞斯的回答,MSKB文章,我的API瀏覽器嗅探可以總結如下:

  1. CreateFile稱爲打開音量。 (所有方法)。
  2. DeviceIoControlFSCTL_LOCK_VOLUME調用。(所有方法)。
  3. DeviceIoControlFSCTL_DISMOUNT_VOLUME調用。 (僅適用於Andreas和MSKB方法,因爲某些原因,資源管理器不會調用這個方法,這個IOCTL似乎影響了驅動器是否在資源管理器中變灰,我不確定爲什麼Explorer不調用它)。
  4. DeviceIoControlIOCTL_STORAGE_MEDIA_REMOVALPREVENT_MEDIA_REMOVAL調用的成員設置爲FALSE(MSKB和Explorer方法,這一步從Andreas的答案中丟失)。
  5. DeviceIoControlIOCTL_STORAGE_EJECT_MEDIA(Andreas和MSKB文章)或IOCTL_DISK_EJECT_MEDIA(資源管理器;請注意,這個IOCTL已經過時,並替換爲STORAGE IOCTL,不知道爲什麼Explorer仍然使用舊的)。

最後,我決定遵循MSKB文章中列出的步驟,因爲它似乎是最徹底和最完整的過程,並且備有MSKB文章。

0

要按照描述here所述關閉驅動器托盤,但不要使用帶有IOCTL_STORAGE_EJECT_MEDIA的DeviceIoControl,而需要使用IOCTL_STORAGE_LOAD_MEDIA調用DeviceIoControl。