http://www.yeahware.com/download/eject.zip 选择Show hidden device后在USB Mass Storage Device处就是Eject了!!!
关键代码
function CM_Get_DevNode_Status(pulStatus: PULong; pulProblemNumber: PULong; dnDevInst: DWord; ulFlags: ULong): DWord; stdcall; external CfgMgr32ModuleName name 'CM_Get_DevNode_Status';
function CM_Request_Device_Eject(dnDevInst: DWord; out pVetoType: TPNPVetoType; pszVetoName: PChar; ulNameLength: ULong; ulFlags: ULong): DWord; stdcall; external SetupApiModuleName name 'CM_Request_Device_EjectA';
if (CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst, 0) <> CR_SUCCESS) then begin exit; end; VetoName[0] := #0; case CM_Request_Device_Eject(DeviceInfoData.DevInst, VetoType, @VetoName, SizeOf(VetoName), 0) of CR_SUCCESS: begin MessageBox(Handle, PChar(’Eject OK (Veto: ' + VetoName + ')'), 'Vetoed', MB_OK); end; CR_REMOVE_VETOED: begin MessageBox(Handle, PChar('Failed to eject the Device (Veto: ' + VetoName + ')'), 'Vetoed', MB_OK); end; else begin MessageBox(Handle, PChar('Failed to eject the Device (' + SysErrorMessage(GetLastError) + ')'), 'Failure', MB_OK); end; end;
那个Eject原代码是有Bug的,修正如下
添加 function TForm1.GetDevInfo(var hDevInfo: hDevInfo): boolean; begin // Get a handle to all devices in all classes present on system hDevInfo := SetupDiGetClassDevs(nil, nil, 0, DIGCF_PRESENT or DIGCF_ALLCLASSES); Result := hDevInfo <> Pointer(INVALID_HANDLE_VALUE); end;
调用为: procedure TForm1.FormCreate(Sender: TObject); begin if (not LoadSetupAPI) then begin ShowMessage('Could not load SetupAPI.dll'); exit; end; DevInfo := nil; ShowHidden := false; // Get a handle to all devices in all classes present on system if not GetDevInfo(DevInfo) then begin ShowMessage('GetClassDevs'); exit; end; // Get the Images for all classes, and bind to the TreeView ClassImageListData.cbSize := SizeOf(TSPClassImageListData); if (not SetupDiGetClassImageList(ClassImageListData)) then begin ShowMessage('GetClassImageList'); exit; end; ImageList.Handle := ClassImageListData.ImageList; TreeView.Images := ImageList; // Add the devices to the TreeView window. EnumAddDevices(ShowHidden, TreeView, DevInfo); end;
procedure TForm1.mRefreshDisplayClick(Sender: TObject); begin if not GetDevInfo(DevInfo) then begin ShowMessage('GetClassDevs'); exit; end; EnumAddDevices(ShowHidden, TreeView, DevInfo); end;
case CM_Request_Device_Eject(DeviceInfoData.DevInst, VetoType, @VetoName, SizeOf(VetoName), 0) of CR_SUCCESS: begin MessageBox(Handle, 'Successful to eject the Device', 'Done', MB_OK); if not GetDevInfo(DevInfo) then begin ShowMessage('GetClassDevs'); exit; end; EnumAddDevices(ShowHidden, TreeView, DevInfo); end;
http://www.yeahware.com/download/eject.zip
选择Show hidden device后在USB Mass Storage Device处就是Eject了!!!
关键代码
function CM_Get_DevNode_Status(pulStatus: PULong; pulProblemNumber: PULong;
dnDevInst: DWord; ulFlags: ULong): DWord; stdcall;
external CfgMgr32ModuleName name 'CM_Get_DevNode_Status';
function CM_Request_Device_Eject(dnDevInst: DWord; out pVetoType: TPNPVetoType;
pszVetoName: PChar; ulNameLength: ULong; ulFlags: ULong): DWord; stdcall;
external SetupApiModuleName name 'CM_Request_Device_EjectA';
if (CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst, 0) <> CR_SUCCESS) then
begin
exit;
end;
VetoName[0] := #0;
case CM_Request_Device_Eject(DeviceInfoData.DevInst, VetoType, @VetoName, SizeOf(VetoName), 0) of
CR_SUCCESS:
begin
MessageBox(Handle, PChar(’Eject OK (Veto: ' + VetoName + ')'), 'Vetoed', MB_OK); end;
CR_REMOVE_VETOED:
begin
MessageBox(Handle, PChar('Failed to eject the Device (Veto: ' + VetoName + ')'), 'Vetoed', MB_OK);
end;
else
begin
MessageBox(Handle, PChar('Failed to eject the Device (' + SysErrorMessage(GetLastError) + ')'), 'Failure', MB_OK);
end;
end;
那个Eject原代码是有Bug的,修正如下
添加
function TForm1.GetDevInfo(var hDevInfo: hDevInfo): boolean;
begin
// Get a handle to all devices in all classes present on system
hDevInfo := SetupDiGetClassDevs(nil, nil, 0, DIGCF_PRESENT or DIGCF_ALLCLASSES);
Result := hDevInfo <> Pointer(INVALID_HANDLE_VALUE);
end;
调用为:
procedure TForm1.FormCreate(Sender: TObject);
begin
if (not LoadSetupAPI) then
begin
ShowMessage('Could not load SetupAPI.dll');
exit;
end;
DevInfo := nil;
ShowHidden := false;
// Get a handle to all devices in all classes present on system
if not GetDevInfo(DevInfo) then
begin
ShowMessage('GetClassDevs');
exit;
end;
// Get the Images for all classes, and bind to the TreeView
ClassImageListData.cbSize := SizeOf(TSPClassImageListData);
if (not SetupDiGetClassImageList(ClassImageListData)) then
begin
ShowMessage('GetClassImageList');
exit;
end;
ImageList.Handle := ClassImageListData.ImageList;
TreeView.Images := ImageList;
// Add the devices to the TreeView window.
EnumAddDevices(ShowHidden, TreeView, DevInfo);
end;
procedure TForm1.mRefreshDisplayClick(Sender: TObject);
begin
if not GetDevInfo(DevInfo) then
begin
ShowMessage('GetClassDevs');
exit;
end;
EnumAddDevices(ShowHidden, TreeView, DevInfo);
end;
case CM_Request_Device_Eject(DeviceInfoData.DevInst, VetoType, @VetoName, SizeOf(VetoName), 0) of
CR_SUCCESS:
begin
MessageBox(Handle, 'Successful to eject the Device', 'Done', MB_OK);
if not GetDevInfo(DevInfo) then
begin
ShowMessage('GetClassDevs');
exit;
end;
EnumAddDevices(ShowHidden, TreeView, DevInfo);
end;