2008-09-12 8 views
8

Có ai biết phương pháp lập trình đóng khay CD trên Windows 2000 trở lên không? Mở khay CD tồn tại, nhưng tôi dường như không thể đóng nó đặc biệt là dưới W2k.Windows CDROM Eject

Tôi đặc biệt đang tìm kiếm một phương pháp để thực hiện việc này từ một tệp lô, nếu có thể, nhưng các cuộc gọi API sẽ ổn.

Trả lời

5

Dưới đây là một cách dễ dàng bằng cách sử dụng API Win32:


[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

Tính năng này hoạt động như thế nào trên một hệ thống có nhiều ổ đĩa? Tôi không thấy bất cứ điều gì để chỉ định một ổ đĩa. – OwenP

+3

-1 Bỏ phiếu xuống, mci là một công nghệ cổ đại (Win3.x) và chỉ hoạt động tốt cho một ổ đĩa đơn. Ngoài ra windows media player phải được cài đặt? nhưng không chắc chắn. Các phiên bản 'N' của châu Âu không đi kèm với Media Player, vì vậy hãy cẩn thận. – unixman83

+0

@unixman phương án được đề xuất là gì? Đó có phải là DeviceIoControl không? – jalf

1

Nircmd là tiện ích dòng lệnh phần mềm miễn phí rất tiện dụng với các tùy chọn khác nhau, bao gồm mở và đóng khay CD.

+0

FYI: www.nirsoft.net bị công ty của tôi chặn và tôi đã tìm thấy thông tin này về chương trình. http://spywarefiles.prevx.com/RRIDCH001610050/NIRCMD.EXE.html – kenny

+1

Đọc mô tả đó không làm tôi lo lắng - có vẻ như họ lo lắng về Nircmd vì đó là một tiện ích có thể làm mọi thứ. Cả Sophos, Avast lẫn ESET đều không chặn nircmd trên bất kỳ hệ thống nào của tôi, ở nhà hay tại nơi làm việc. Mặt khác tôi chưa bao giờ nghe nói về Prevx. –

11

tôi loại muốn sử dụng DeviceIOControl vì nó mang lại cho tôi khả năng để đẩy bất kỳ loại ổ đĩa di động (như USB và đèn flash-đĩa như cũng như khay CD). Đà codez đúng đẩy một đĩa sử dụng DeviceIOControl được (chỉ cần thêm lỗi xử lý thích hợp):

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; 
} 
+0

Điều này làm việc tuyệt vời, nhưng lưu ý chính tả chính xác 'DeviceIoControl' (không có vốn' O'). – Nate

+0

@Nate: Cảm ơn, đã sửa nó! –

+0

Làm cách nào để sử dụng mã này, ngôn ngữ là gì? – deed02392

3

tôi nhận thấy rằng câu trả lời Andreas Magnusson đã làm không hoàn toàn công việc chính xác giống như nút Eject Explorer đã làm. Cụ thể, ổ đĩa không có màu xám trong Explorer bằng mã Andreas, nhưng nếu bạn sử dụng lệnh Eject. Vì vậy, tôi đã làm một số điều tra.

Tôi chạy API Monitor trong khi chạy lệnh Eject từ Explorer (Windows 7 SP1 64-bit). Tôi cũng tìm thấy một bài viết MSKB tốt 165721 có tiêu đề How To Ejecting Removable Media in Windows NT/Windows 2000/Windows XP. Phần thú vị nhất của bài viết MSKB được trích dẫn dưới đây:

  1. Gọi CreateFile với GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, và OPEN_EXISTING. Tham số lpFileName phải là \. \ X: (trong đó X là ký tự ổ đĩa thực). Tất cả các thông số khác có thể bằng không.
  2. Khóa ổ đĩa bằng cách phát hành FSCTL_LOCK_VOLUME IOCTL qua DeviceIoControl. Nếu bất kỳ ứng dụng nào khác hoặc hệ thống đang sử dụng âm lượng, IOCTL này không thành công. Khi hàm này trả về thành công, ứng dụng được đảm bảo rằng ổ đĩa không được sử dụng bởi bất kỳ thứ gì khác trong hệ thống.
  3. Ngắt kết nối âm lượng bằng cách phát hành FSCTL_DISMOUNT_VOLUME IOCTL. Điều này làm cho hệ thống tệp loại bỏ tất cả kiến ​​thức về khối lượng và loại bỏ bất kỳ thông tin nội bộ nào mà nó giữ liên quan đến khối lượng.
  4. Đảm bảo phương tiện có thể bị xóa bằng cách phát hành IOCTL_STORAGE_MEDIA_REMOVAL IOCTL. Đặt thành viên PreventMediaRemoval của cấu trúc PREVENT_MEDIA_REMOVAL thành FALSE trước khi gọi IOCTL này. Điều này ngăn chặn thiết bị ngăn chặn việc loại bỏ các phương tiện truyền thông.
  5. Loại bỏ phương tiện với IOCTL_STORAGE_EJECT_MEDIA IOCTL. Nếu thiết bị không cho phép tự động đẩy, thì IOCTL_STORAGE_EJECT_MEDIA có thể bị bỏ qua và người dùng có thể được hướng dẫn loại bỏ phương tiện.
  6. Đóng bộ điều khiển âm lượng thu được trong bước đầu tiên hoặc phát hành FSCTL_UNLOCK_VOLUME IOCTL. Điều này cho phép biến tần được sử dụng bởi các quá trình khác.

câu trả lời Andreas, những bài viết MSKB, và API của tôi đánh hơi của Explorer có thể được tóm tắt như sau:

  1. CreateFile gọi để mở âm lượng. (Tất cả các phương pháp).
  2. DeviceIoControl gọi với FSCTL_LOCK_VOLUME.(Tất cả các phương pháp).
  3. DeviceIoControl gọi với FSCTL_DISMOUNT_VOLUME. (Chỉ có các phương thức của Andreas và MSKB. Explorer không gọi điều này vì một lý do nào đó. IOCTL này dường như là những gì ảnh hưởng đến việc ổ đĩa có chuyển sang màu xám trong Explorer hay không. Tôi không chắc tại sao Explorer không gọi nó).
  4. DeviceIoControl được gọi với IOCTL_STORAGE_MEDIA_REMOVALPREVENT_MEDIA_REMOVAL thành viên được đặt thành FALSE (phương thức MSKB và Explorer. Bước này không có trong câu trả lời của Andreas).
  5. DeviceIoControl gọi với IOCTL_STORAGE_EJECT_MEDIA (bài viết của Andreas và MSKB) hoặc IOCTL_DISK_EJECT_MEDIA (Explorer; lưu ý IOCTL này đã lỗi thời và được thay thế bằng IOCTL BẢO QUẢN. Không chắc chắn tại sao Explorer vẫn sử dụng cũ).

Để kết thúc, tôi quyết định làm theo quy trình được nêu trong bài viết MSKB, vì nó có vẻ là thủ tục triệt để nhất và đầy đủ, được sao lưu bằng bài viết MSKB.

+0

Áp phích ban đầu đang hỏi cách đóng khay CD-ROM, không đẩy khay. –

+0

@RossRidge: Và đó là lý do tại sao tiêu đề đọc "Windows CDROM Eject"? –

+0

Mặc dù tiêu đề, câu hỏi là rõ ràng. "Có ai biết một phương pháp lập trình ** đóng ** khay CD trên Windows 2000 trở lên không?" –

0

Để đóng khay ổ đĩa như mô tả here nhưng thay vì sử dụng DeviceIoControl với IOCTL_STORAGE_EJECT_MEDIA, bạn cần gọi DeviceIoControl bằng IOCTL_STORAGE_LOAD_MEDIA.