关于C#:使用Win32 API安全删除USB驱动器?

关于C#:使用Win32 API安全删除USB驱动器?

Safely remove a USB drive using the Win32 API?

如何使用Win32 API移除USB驱动器? 我在嵌入式系统上做了很多工作,在其中一个系统上,我必须将程序复制到USB记忆棒上并将其插入目标硬件。

由于我主要在控制台上工作,所以我不喜欢使用鼠标每天单击数百次单击任务栏上的小图标。

我很想编写一个小程序来完成该操作,以便可以将其放入我的makefile中,但是我还没有找到任何执行相同操作的API调用。

有任何想法吗?


您可以使用CM_Request_Device_Eject()函数以及其他一些可能性。
请参阅以下项目和文章:

DevEject:直截了当。
http://www.withopf.com/tools/deveject/

有用的CodeProject文章:
http://www.codeproject.com/KB/system/RemoveDriveByLetter.aspx


看起来Sync使您可以指定-e弹出可移动驱动器。尽管不是win32 API,您可能只需要从makefile中调用sync -e [drive_letter]


这是有关可移动存储介质的Technet文章。寻找DismountNtmsMedia


这是Delphi中的一个解决方案,我已经对其进行了修改并将其投入服务以供大型企业使用。转到:链接文本

查找" scapi(安装和配置管理器API)",然后下载。将有一个名为USBView的演示程序,它将带您上路。如果您有Delphi,它还包含一个TUSBDeviceTree组件,您可以在该组件时收集有关USB设备的信息。

问候


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include<SetupAPI.h>
#include <windows.h>  
#include<initguid.h>
#include <newdev.h>
#include <Cfgmgr32.h>

#pragma comment(lib,"Cfgmgr32.lib")
#pragma comment(lib,"Setupapi.lib")
#pragma comment(lib,"Newdev.lib")

int RemoveDevice(const GUID *guid, const wchar_t *hwID) {
    HDEVINFO m_hDevInfo;
    SP_DEVICE_INTERFACE_DATA         spdid;
    SP_DEVINFO_DATA                  spdd;
    DWORD                            dwSize;
    BYTE Buf[1024];
    PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd =
        (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;

    printf("try to remove device::%ws\
"
, hwID);

    m_hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT| DIGCF_DEVICEINTERFACE);
    if (m_hDevInfo == INVALID_HANDLE_VALUE)
    {
        printf("GetClassDevs Failed!\
"
);
        return 0;
    }
    spdid.cbSize = sizeof(spdid);
    for (int i = 0; SetupDiEnumDeviceInterfaces(m_hDevInfo, NULL, guid, i, &spdid); i++) {
        dwSize = 0;
        SetupDiGetDeviceInterfaceDetail(m_hDevInfo,
            &spdid, NULL, 0, &dwSize, NULL);
        if (dwSize != 0 && dwSize <= sizeof(Buf)) {
            pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!

            ZeroMemory((PVOID)&spdd, sizeof(spdd));
            spdd.cbSize = sizeof(spdd);

            long res =
                SetupDiGetDeviceInterfaceDetail(m_hDevInfo, &
                    spdid, pspdidd,
                    dwSize, &dwSize,
                    &spdd);
            if (res) {
                OLECHAR* guidString;
                OLECHAR* guidString2;
                StringFromCLSID(&spdd.ClassGuid, &guidString);
                StringFromCLSID(&spdid.InterfaceClassGuid, &guidString2);
                printf("%d, %ws, %ws, %ws\
"
, spdd.DevInst, pspdidd->DevicePath, guidString, guidString2);
                CoTaskMemFree(guidString);
                CoTaskMemFree(guidString2);
                if (!memcmp(pspdidd->DevicePath, hwID, 2 * lstrlenW(hwID))) {
                    DEVINST DevInstParent = 0;
                    res = CM_Get_Parent(&DevInstParent, spdd.DevInst, 0);
                    for (long tries = 0; tries < 10; tries++) {
                        // sometimes we need some tries...
                        WCHAR VetoNameW[MAX_PATH];
                        PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
                        VetoNameW[0] = 0;

                        res = CM_Request_Device_EjectW(DevInstParent,
                            &VetoType, VetoNameW, MAX_PATH, 0);
                        if ((res == CR_SUCCESS &&
                            VetoType == PNP_VetoTypeUnknown)) {
                            printf("remove %ws success!\
"
, pspdidd->DevicePath);
                            SetupDiDestroyDeviceInfoList(m_hDevInfo);
                            return 1;
                        }
                        Sleep(500); // required to give the next tries a chance!
                    }
                    break;
                }
            }
        }
    }
    printf("Remove Device Failed!\
"
);
    SetupDiDestroyDeviceInfoList(m_hDevInfo);
    return 0;
}

int main(){
    GUID GUID_DEVINTERFACE_USB_HUB;
    CLSIDFromString(L"F18A0E88-C30C-11D0-8815-00A0C906BED8", &GUID_DEVINTERFACE_USB_HUB);

    RemoveDevice(&GUID_DEVINTERFACE_USB_HUB, L"\\\\\\\\?\\\\usb#root_hub30");
    return 0;
}

引用:

如何准备USB驱动器以安全移除

GUID_DEVINTERFACE


推荐阅读