谁能给一个u盘卸载弹出的例子?

XHWXHWXHWchuBuLai 2010-07-12 04:04:14
我的程序卸载u盘时只能够让u盘图标上面打个问号,但是u盘并没有弹出,盘还在转,u盘上面的灯还在亮着......
还得用鼠标右键那个任务栏上面的托盘图标,点击一次卸载,才把u盘卸掉了。如何能一步到位呢?我使用的代码如下所示,如果没有现成的历程的话,帮忙看下问题在哪里,怎么改?


int PopUDisk(CString UName)
{
HANDLE hDevice = NULL;// handle to the drive to be examined
BOOL bResult = FALSE;// results flag
DWORD junk = 0;// discard results
DWORD dwError = 0;
int Result = 0;

CString strTemp = _T("\\\\.\\");
strTemp+=UName;
// Open the volume
//hDevice = CreateFileW( "\\\\.\\I: ",// drive to open
hDevice = CreateFileW(strTemp,// drive to open
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,// share mode
NULL,// default security attributes
OPEN_EXISTING,// disposition
0,// file attributes
NULL);// don 't copy any file 's attributes

if(hDevice == INVALID_HANDLE_VALUE)// can 't open the drive
{
dwError = GetLastError();
//AfxMessageBox( "Fail to create file! ");
return 1;//创建文件设备句柄失败
}
//Dismount the volume
bResult = DeviceIoControl(hDevice,// handle to volume
FSCTL_DISMOUNT_VOLUME,// dwIoControlCode
//IOCTL_STORAGE_EJECT_MEDIA,
NULL,// lpInBuffer
0,// nInBufferSize
NULL,// lpOutBuffer
0,// nOutBufferSize
&junk,// discard count of bytes returned
(LPOVERLAPPED)NULL);// synchronous I/O

if(!bResult)// IOCTL failed
{
dwError = GetLastError();
//AfxMessageBox( "Fail to dismount the volume! ");
Result = 2;//卸载u盘失败!
}

// Close the volume handle
bResult = CloseHandle(hDevice);
if(!bResult)
{
dwError = GetLastError();
//AfxMessageBox( "Fail to close handle! ");
return 3;
}

return Result;//success result is 0
}
...全文
368 点赞 收藏 11
写回复
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
stkevin 2011-03-28
我想问一下,有没有可以用的代码 急需啊
回复
4楼的,你这代码有什么用处呀?我要是不会查找u盘的话,我还写个这样的函数这样的形参干吗呢?你的卸载u盘操作和我写的代码有区别吗?
回复
先谢谢各位的回帖。我去试试,都好用的话就都给分!
回复
Eleven 2010-07-13
回复
dulvtianya 2010-07-13
HANDLE hDevice; // handle to the drive to be examined
BOOL bResult; // results flag
DWORD junk; // discard results
DWORD dwError;
// Open the volume
hDevice = CreateFile( "\\\\.\\I: ", // drive to open
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // don 't copy any file 's attributes

if (hDevice == INVALID_HANDLE_VALUE) // can 't open the drive
{
dwError = GetLastError();
AfxMessageBox( "Fail to create file! ");
return ;
}

//Dismount the volume
bResult = DeviceIoControl(
hDevice, // handle to volume
FSCTL_DISMOUNT_VOLUME, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
NULL, // lpOutBuffer
0, // nOutBufferSize
&junk, // discard count of bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
if (!bResult) // IOCTL failed
{
dwError = GetLastError();
AfxMessageBox( "Fail to dismount the volume! ");
}

// Close the volume handle
bRet = CloseHandle(hDevice);
if (!bRet)
{
dwError = GetLastError();
AfxMessageBox( "Fail to close handle! ");
}

CreateFile所用I盘符是我测试时用的,要获取用户当前插入的U盘的盘符可以采用如下方法:
1)添加WM_DEVICECHANGE的消息处理函数OnDeviceChange,在该函数中捕获DBT_DEVICEARRIVAL事件(当U盘插入时,OS会发WM_DEVICECHANGE广播消息,该消息的wParam中会包含DBT_DEVICEARRIVAL事件),同时得到DEV_BROADCAST_VOLUME结构的数据,DEV_BROADCAST_VOLUME结构的dbcv_unitmask成员是一个Mask变量,最低位对应A,其次是B,...,根据它可就可以得到当前U盘的盘符了.
BOOL CMainFrame::OnDeviceChange( UINT nEventType, DWORD dwData)
{
PDEV_BROADCAST_HDR pDevBroadcastHdr;
PDEV_BROADCAST_VOLUME pDevBroadcastVolume;
CString strVolume= " ";
switch (nEventType)
{
case DBT_DEVICEARRIVAL:
pDevBroadcastHdr = (PDEV_BROADCAST_HDR) dwData;
if (pDevBroadcastHdr-> dbch_devicetype == DBT_DEVTYP_VOLUME)
{
pDevBroadcastVolume = (PDEV_BROADCAST_VOLUME)pDevBroadcastHdr;
xJudgeDeviceChangePath(pDevBroadcastVolume-> dbcv_unitmask,strVolume);
}
break;
......
default:
return TRUE;
}
.......
}

xJudgeDeviceChangePath的代码如下:
void xJudgeDeviceChangePath(DWORD dwData, CString &strPath)

{

char i;

for (i = 0; i < 26; ++i)

{

if (dwData & 0x1)

{

CString str = char(i+ 'A ');

strPath = str+_T( ": ");

break;

}

dwData = dwData > > 1;

if(dwData == 0x0000) break;

}

}
回复
船过水无痕 2010-07-13
TCHAR sEnumerator[] = _T("USB");
//HDEVINFO hDev;
DWORD dwIndex;
SP_DEVINFO_DATA devInfo;

BYTE Buffer[300];
DWORD BufferSize = 0;
DWORD DataType;
SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)};

Sleep(2000);
while (1)
{
Sleep(100);
HDEVINFO m_hDev;
m_hDev = SetupDiGetClassDevs(NULL, sEnumerator, NULL, DIGCF_ALLCLASSES);

if (m_hDev != INVALID_HANDLE_VALUE)
{
dwIndex = 0;
memset(&devInfo, 0, sizeof(devInfo));
devInfo.cbSize = sizeof(devInfo);

while (SetupDiEnumDeviceInfo(m_hDev, dwIndex ++, &devInfo))
{
if (SetupDiGetDeviceRegistryProperty(m_hDev,&devInfo,SPDRP_DEVICEDESC,&DataType,Buffer,sizeof(Buffer),&BufferSize))
{
char Bufferstring[300];
memcpy(Bufferstring,Buffer,sizeof(Buffer));
CString Buffer_CString;
Buffer_CString = Bufferstring;

if (Buffer_CString.CompareNoCase("USB Mass Storage Device") == 0)
{
//if (!SetupDiSetDeviceRegistryProperty(m_hDev,&devInfo,SPDRP_LOWERFILTERS ,NULL,0))
//{
// TRACE("SetupDiSetDeviceRegistryProperty = %d\n",GetLastError());
//}USB 措侩樊 历厘家 厘摹

if ( SetupDiRemoveDevice(m_hDev, &devInfo) )
{
printf("success\n");
}
else{
printf("error\n");
}

// Call the ClassInstaller and perform the change.
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,m_hDev,&devInfo))
{
continue ;
}

PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
PropChangeParams.StateChange = DICS_DISABLE;
if (!SetupDiSetClassInstallParams(m_hDev,&devInfo,(SP_CLASSINSTALL_HEADER *)&PropChangeParams,sizeof(PropChangeParams)))
{
continue ;
}
// Call the ClassInstaller and perform the change.
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,m_hDev,&devInfo))
{
continue ;
}

if ( SetupDiRemoveDevice(m_hDev, &devInfo) )
{
printf("success\n");

}
else{
printf("error\n");
}

// Call the ClassInstaller and perform the change.
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,m_hDev,&devInfo))
{
continue ;
}

}
}
}
}

SetupDiDestroyDeviceInfoList(m_hDev);

}
回复
没有人知道吗?我同事用Delphi都可以实现这个功能的,卸载掉u盘的,我想vc肯定有办法实现的?
回复
嘿嘿,到底u盘还是弹出来了,但是把其它u盘一起都弹出来了-_-!,这个答案呀是综合了几个人的回答呀,这个给分儿呀,还得考虑下了。要是能弹出指定盘符的u盘就好喽!明天接帖子,如果有更好的回答的话:)
回复
yeah2000 2010-07-13
http://download.csdn.net/source/2539393
这个不错,我用的。支持检测,卸载,获得盘符...
回复
m_tornado 2010-07-13
mark,前两天也是写这个没弄出来~
回复
kemee 2010-07-12
。。。。。。这个沙发掉同学习。。。。。。。
回复
发动态
发帖子
硬件/系统
创建于2007-09-28

2590

社区成员

VC/MFC 硬件/系统
申请成为版主
社区公告
暂无公告