在退出时调用这个函数:
#include <SetupAPI.au3>
#include <Thread.au3>
OnAutoItExitRegister("_SafelyEjectOnExit")
MsgBox(48, "", "Close all the windows and processes that using this application, " & _
"and then you can safely unplug the disk when exiting.")
Func _SafelyEjectOnExit()
Local $hDevs, $tDevInfo, $tDevIfInfo, $aInterface, $iDisk
Local $sDevicePath, $hDevInst, $iDisk, $iStatus, $sDeviceId
$iDisk = _CM_Get_Drive_Disk_Number(StringLeft(@ScriptFullPath, 2))
$aInterface = _CM_Get_Device_Interface_List($GUID_DEVINTERFACE_DISK)
For $i = 1 To $aInterface[0]
$sDevicePath = StringTrimLeft($aInterface[$i], 4)
If _CM_Get_Drive_Disk_Number($sDevicePath) = $iDisk Then
ExitLoop _CM_Assign_Var($sDevicePath, $aInterface[$i], 1)
EndIf
Next
If StringLeft($sDevicePath, 4) <> "\\?\" Then Exit
_SetupDiGetDeviceInterfaceDevsEx($sDevicePath, $hDevs, $tDevInfo)
$hDevInst = DllStructGetData($tDevInfo, "DevInst")
$iStatus = _CM_Get_DevNode_Status($hDevInst)
If BitAnd($iStatus, $DN_REMOVABLE) = 0 Then
$hDevInst = _CM_Get_Parent($hDevInst)
$iStatus = _CM_Get_DevNode_Status($hDevInst)
If BitAnd($iStatus, $DN_REMOVABLE) = 0 Then
Exit
EndIf
EndIf
$sDeviceId = _CM_Get_Device_ID($hDevInst)
Local $hProcess, $pStartAddr, $bCode
$hProcess = _RTOpenProcess("explorer.exe")
_RTLoadDllEx(@SystemDir & "\SetupApi.dll", $hProcess)
$pStartAddr = _RTVirtualAllocEx($hProcess, 1024)
$bCode = "0x558BEC5356BB" & _RTLongPtrToBytes($pStartAddr + 65) & _
"6800040000FF530C33C0508BF450FF750856FF1385C0751650505050" & _
"FF36FF530485C0750950505050FF36FF530883C4045E5B5DC20400" & _
_RTLongPtrToBytes(_RTGetProcAddress("SetupApi.dll", "CM_Locate_DevNodeW")) & _
_RTLongPtrToBytes(_RTGetProcAddress("SetupApi.dll", "CM_Query_And_Remove_SubTreeW")) & _
_RTLongPtrToBytes(_RTGetProcAddress("SetupApi.dll", "CM_Request_Device_EjectW")) & _
_RTLongPtrToBytes(_RTGetProcAddress("Kernel32.dll", "Sleep")) & _
_RTStringToBytesW($sDeviceId) & "0000"
_RTInjectEx($hProcess, $pStartAddr, $bCode)
_RTCloseHandle(_RTCreateRemoteThread($hProcess, $pStartAddr, $pStartAddr + 81))
_RTCloseHandle($hProcess)
EndFunc ;==>_SafelyEjectOnExit
|