文章目录

  • 前言
  • 一、利用OS API实现对U盘的管理
  • 二、项目到底长啥样
  • 三、实例代码
    • 1.实时判断U盘插入与拔出
    • 2.能够显示U盘的总容量、使用容量和剩余容量
    • 3.能够将某个目录上的文件或整个目录复制到U盘上
    • 4. 删除U盘上文件
    • 5.禁止U盘的使用及开启U盘的使用
    • 6.尝试读取PCB信息
  • 四、总结

前言

MFC实现对U盘的管理并用图形化界面展示出来。


项目下载地址
MFC教程

一、利用OS API实现对U盘的管理

  • 能够判断U盘是否存在
  • 能够显示U盘的总容量、使用容量和剩余容量;
  • 能够将某个目录上的文件或整个目录复制到U盘上;
  • 可以删除U盘上文件;
  • 禁止U盘的使用及开启U盘的使用;
  • 推荐使用C# winform,也可以使用其它语言;
  • 体会OS的API的作用; 尝试读取PCB信息;
  • 其它创意。 项目最终能以图形界面的形式完成。

二、项目到底长啥样

三、实例代码

本项目主要采用MFC(微软基础类库)开发一个Windows窗体程序,实现对U盘的管理。项目第一个功能以及使用MFC开发的idea源自一位学长。其余功能由自己通过网上查阅资料实现。
项目传送门:
https://blog.csdn.net/qq_39861376/article/details/102678582

1.实时判断U盘插入与拔出

OnDeviceChange(UINT nEventType, DWORD dwData):
首先设置消息映射

afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);
BEGIN_MESSAGE_MAP(CMFCUSBDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, &CMFCUSBDlg::OnBnClickedButton1)//ON_WM_ACTIVATE()ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()

注册USB设备消息,不注册消息处理函数无法响应, 只有注册了该设备,OnDeviceChange才能获得详细的信息,否则收到的nEventType参数都是0007,dwData无数据。

BOOL CMFCUSBDlg::OnInitDialog()// 注意向OnInitDialog中添加如下代码;DEV_BROADCAST_DEVICEINTERFACE Filter;ZeroMemory(&Filter, sizeof(Filter));Filter.dbcc_size = sizeof(Filter);   // size gets set to 29 with 1-byte packing or 32 with 4- or 8-byte packingFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;Filter.dbcc_classguid = {0xA5DCBF10,0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };//DEVICE_NOTIFY_ALL_INTERFACE_CLASSES //关注所有设备事件RegisterDeviceNotification(this->m_hWnd, &Filter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);if (NULL == RegisterDeviceNotification(this->m_hWnd, &Filter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES))TRACE("RegisterDeviceNotification failed!!");

常见的GUID
GUID:
https://blog.csdn.net/diyu122222/article/details/79791073

C/C++ code
static const GUID GUID_DEVINTERFACE_LIST[] =
{// GUID_DEVINTERFACE_USB_DEVICE{ 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } },// GUID_DEVINTERFACE_DISK{ 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } },// GUID_DEVINTERFACE_HID, { 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } },// GUID_NDIS_LAN_CLASS{ 0xad498944, 0x762f, 0x11d0, { 0x8d, 0xcb, 0x00, 0xc0, 0x4f, 0xc3, 0x35, 0x8c } }GUID_DEVINTERFACE_COMPORT//{ 0x86e0d1e0, 0x8089, 0x11d0, { 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73 } },GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR//{ 0x4D36E978, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } },GUID_DEVINTERFACE_PARALLEL//{ 0x97F76EF0, 0xF883, 0x11D0, { 0xAF, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x5C } },GUID_DEVINTERFACE_PARCLASS//{ 0x811FC6A5, 0xF728, 0x11D0, { 0xA5, 0x37, 0x00, 0x00, 0xF8, 0x75, 0x3E, 0xD1 } }
};

接受设备变更消息:

BOOL CMFCUSBDlg::OnDeviceChange(UINT nEventType, DWORD dwData)
{//const int DBT_DEVICEARRIVAL = 0x8000; // system detected a new device//public const int DBT_DEVICEQUERYREMOVE = 0x8001;   // Preparing to remove (any program can disable the removal)//const int DBT_DEVICEREMOVECOMPLETE = 0x8004; // removed //const int DBT_DEVTYP_VOLUME = 0x00000002;//DEV_BROADCAST_DEVICEINTERFACE * dbd = (DEV_BROADCAST_DEVICEINTERFACE*)dwData;//CString str;//str.Format(_T("U disk in !"));//SetDlgItemText(IDC_BUTTON1, str);第一个短点,判断是否接收到设备变动的信息CString detectMsg;char  m_decDriver;PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)dwData;switch (nEventType){case DBT_DEVICEARRIVAL:{//第二个断点,判断nEventType传来的值是0007还是0X8000if (lpdb->dbch_devicetype==DBT_DEVTYP_VOLUME)//逻辑卷{PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;switch (lpdbv->dbcv_flags){case 0://U盘{m_decDriver = FirstDriveFromMask(lpdbv->dbcv_unitmask);detectMsg.Format(_T("检测到U盘:[%c]插入!"),m_decDriver);MessageBox(detectMsg);}break;case DBTF_MEDIA://光盘break;}}}break;case DBT_DEVICEREMOVECOMPLETE://   Handle   device   removal{if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)//逻辑卷{PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;switch (lpdbv->dbcv_flags){case 0:                //U盘{m_decDriver = FirstDriveFromMask(lpdbv->dbcv_unitmask);//detectMsg.Format(_T("检测到U盘:[%s]拔出!"), m_decDriver/*.GetBuffer(0)*/);detectMsg.Format(_T("检测到U盘:[%c]拔出!"),m_decDriver);MessageBox(detectMsg);}break;case DBTF_MEDIA:    //光盘break;}}}break;}//CString str;//str.Format(_T("U disk in !"));//SetDlgItemText(IDC_BUTTON1, str);return  TRUE;
}

获取单元掩码

char FirstDriveFromMask(ULONG unitmask)
{char i;for (i = 0; i < 26; ++i){if (unitmask & 0x1)break;unitmask = unitmask >> 1;}return(i + 'A');
}

2.能够显示U盘的总容量、使用容量和剩余容量

按钮事件:

void CMFCUSBDlg::OnBnClickedButton1()
{CString m_decDriver = GetDiskLetter();// 获取盘符INT_PTR nRes;CTipDlg tipDlg;           // 构造对话框类CTipDlg的实例   nRes = tipDlg.DoModal();  // 弹出对话框   //从这里开始UpdateData(true);ULARGE_INTEGER nFreeBytesAvailable;ULARGE_INTEGER nTotalNumberOfBytes;ULARGE_INTEGER nTotalNumberOfFreeBytes;//lpDirectoryName 是驱动器的名称。//lpFreeBytesAvailableToCaller 是用户可用的磁盘空间。//lpTotalNumberOfBytes 是磁盘总共的空间。//lpTotalNumberOfFreeBytes 是磁盘空闲的空间。以上都是字节为单位。if (GetDiskFreeSpaceEx(m_decDriver + ":", &nFreeBytesAvailable, &nTotalNumberOfBytes, &nTotalNumberOfFreeBytes)){CString str;str.Format(_T("用户可用的磁盘空间:%.2fGB\n磁盘总空间:%.2fGB\n磁盘空闲空间:%.2fGB\n"), (GB(nFreeBytesAvailable)), (GB(nTotalNumberOfBytes)), (GB(nTotalNumberOfFreeBytes)));MessageBox(str, _T("磁盘信息"), MB_OK);}UpdateData(false);
}

获取盘符:

CString GetDiskLetter()
{CString strDiskLetter = _T("");LPTSTR lpDrives = new TCHAR[MAX_PATH];DWORD dwLen = ::GetLogicalDriveStrings(MAX_PATH, lpDrives);CString sDrives[26];for (DWORD nIndex = 0; nIndex < dwLen / 4; nIndex++){if (::GetDriveType(lpDrives + nIndex * 4) == DRIVE_REMOVABLE){sDrives[nIndex] += (CString)(lpDrives + nIndex * 4);if (sDrives[nIndex] != _T("A://") && sDrives[nIndex] != _T("B://")){CString usbPath = sDrives[nIndex];strDiskLetter = usbPath.Left(1);//AfxMessageBox(strDiskLetter);break;}}}delete lpDrives;return strDiskLetter;
}

字节与GB转化:

float GB(ULARGE_INTEGER TotalNumberOfBytes) {int iTotal = (TotalNumberOfBytes.u.HighPart << 12) + (TotalNumberOfBytes.u.LowPart >> 20);return iTotal / 1024.0;
}

3.能够将某个目录上的文件或整个目录复制到U盘上

获取文件路径:

void CMFCUSBDlg::OnBnClickedButtonfile()
{CString strFile = _T("");CFileDialog    dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files (*.jpg)|*.jpg|All Files (*.*)|*.*||"), NULL);if (dlgFile.DoModal()){strFile = dlgFile.GetPathName();}SetDlgItemText(EditFile, strFile);// TODO: 在此添加控件通知处理程序代码
}

获取目录路径:

void CMFCUSBDlg::OnBnClickedButtondir()
{TCHAR           szFolderPath[MAX_PATH] = { 0 };CString         strFolderPath = TEXT("");BROWSEINFO      sInfo;::ZeroMemory(&sInfo, sizeof(BROWSEINFO));sInfo.pidlRoot = 0;sInfo.lpszTitle = _T("请选择处理结果存储路径");sInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_DONTGOBELOWDOMAIN;sInfo.lpfn = NULL;// 显示文件夹选择对话框  LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);if (lpidlBrowse != NULL){// 取得文件夹名  if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath)){strFolderPath = szFolderPath;}}if (lpidlBrowse != NULL){::CoTaskMemFree(lpidlBrowse);}CString strFile;GetDlgItemText(EditFile, strFile);string dirname = Replace(strFile);string filename;int flag;for (int i = dirname.length() - 1; i >= 0; i--){if (dirname[i] == '/') {flag = i;break;}}for (int i = flag + 1; i < dirname.length(); i++) {filename += dirname[i];}//strFolderPath = strFolderPath + filename;CString cstrTest;cstrTest = CA2T(filename.c_str());SetDlgItemText(EditDir, strFolderPath+cstrTest);//return strFolderPath
}

复制文件:

void CMFCUSBDlg::OnBnClickedButtoncopy()
{//string Ef= "C:/masm/usb/usb.txt";//string Nf = "D:/1usb.txt";CString Ef; GetDlgItemText(EditFile, Ef);CString Nf; GetDlgItemText(EditDir, Nf);CString str;//str.Format(_T("请选择要复制的文件"));if (Replace(Ef)=="") {//cout << 1;str.Format(_T("请选择要复制的文件"));MessageBox(str);       }else if (Replace(Nf) == ""){str.Format(_T("请选择文件复制位置"));MessageBox(str);}else{   wstring stempEf = s2ws(Replace(Ef));wstring stempNf = s2ws(Replace(Nf));LPCWSTR resultEf = stempEf.c_str();LPCWSTR resultNf = stempNf.c_str();// TODO: 在此添加控件通知处理程序代码CString str;str.Format(_T("复制失败,请检查您的文件路径"));if (!CopyFile(resultEf, resultNf, FALSE)){MessageBox(str);}  else {str.Format(_T("Copy successfully!"));MessageBox(str);}}
}

替换函数:

//把\替换成/
string Replace(CString str) {string strTest;//CString转换为StringstrTest = CT2A(str.GetString());for (int i = 0; i < strTest.length(); i++) {if (str[i] == '\\') {strTest = strTest.replace(i, 1, "/");}}return strTest;
}

类型转换函数(string转化为wstring再转换为LPCTSTR):

//string到wstring类型转换,wstring可以转换为LPCTSTR文件
wstring s2ws(const std::string& s) {int len;int slength = (int)s.length() + 1;len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);wchar_t* buf = new wchar_t[len];MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);std::wstring r(buf);delete[] buf;return r.c_str();}

第二种类型转换的方法:

LPCWSTR stringToLPCWSTR(std::string orig)
{size_t origsize = orig.length() + 1;const size_t newsize = 100;size_t convertedChars = 0;wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);return wcstring;
}

第三种类型转化:

直接强转(LPCTSTR)string

4. 删除U盘上文件

获取文件路径:同复制操作
删除文件:

void CMFCUSBDlg::OnBnClickedButtondelete()
{CString Nf;GetDlgItemText(EditFile, Nf);wstring stempNf = s2ws(Replace(Nf));LPCWSTR resultNf = stempNf.c_str();BOOL del = DeleteFile(resultNf);if (del){MessageBox(_T("删除成功"), _T("提示信息"), MB_OK);}else{DWORD error_rus = GetLastError();MessageBox( _T("删除失败"), _T("提示信息"), MB_OK);}}

5.禁止U盘的使用及开启U盘的使用

这里采用更改注册表的方式达到禁用与开启的效果,详情可以见:
https://blog.csdn.net/weixin_44627672/article/details/109430607

void CMFCUSBDlg::OnBnClickedCloseu()
{long lRet;HKEY hKey;lRet = RegCreateKey(HKEY_LOCAL_MACHINE,_T("SYSTEM\\CurrentControlSet\\Services\\USBSTOR"),&hKey);DWORD KeyValue = 4;if (lRet == ERROR_SUCCESS){//MessageBox(_T("right"), _T("Prompt"), MB_OK);lRet = RegSetKeyValue(HKEY_LOCAL_MACHINE,_T("SYSTEM\\CurrentControlSet\\Services\\USBSTOR"),_T("Start"),REG_DWORD,(LPBYTE)&KeyValue,sizeof(DWORD));if (lRet == ERROR_SUCCESS){MessageBox(_T("禁用成功"), _T("Prompt"), MB_OK);}else{MessageBox(_T("禁用失败,请检查您的权限"), _T("Prompt"), MB_OK);}RegCloseKey(hKey);}else {MessageBox(_T("权限不足"), _T("Prompt"), MB_OK);RegCloseKey(hKey);}//open+query查询值/*TCHAR tchData[64];DWORD dwSize;DWORD dwValue, dwType;DWORD dwBufLen = 255;DWORD dwRet;dwSize = sizeof(data);lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,         // handle to open key_T("SYSTEM\\CurrentControlSet\\Services\\USBSTOR"),  // subkey name0,   // reservedKEY_QUERY_VALUE, // security access mask&hKey    // handle to open key);假设start说存储的数据是REG_SZlRet = RegQueryValueEx(hKey,            // handle to key_T("Start"),  // value namesNULL,   // reservedNULL,       // type buffer(LPBYTE)tchData,        // data buffer&dwSize      // size of data buffer);if (RegQueryValueEx(hKey, _T("Start"), NULL, &dwType, (LPBYTE)&dwValue, &dwBufLen) == ERROR_SUCCESS){if (dwType == REG_DWORD)dwRet = dwValue;}else {MessageBox(_T("234"));}RegCloseKey(hKey);*/
}

6.尝试读取PCB信息

这里只获取了PID

//获取PCB信息如PID
void CMFCUSBDlg::OnBnClickedButtonpcb()
{CString str;DWORD csPid;csPid = GetCurrentProcessId();str.Format(_T("PID:%u"), csPid);//SetDlgItemText(IDC_EDIT1, _T("PID:[]"));SetDlgItemText(IDC_EDIT1, str);
}

四、总结

做完这个项目将近三天,因为自己基础不好实现起来不是很容易,好在终于解决了;主要还是提高了自己的文献检索能力(如何快速的从网上获得自己所需要的东西,这点很重要)、以及独立解决问题的能力(一个复杂的问题是如何一步一步解决的。从毫无思路到知道大概思路再到具体实现,不断发现问题解决问题,最后走到终点。)
就像海里航行的船,没有指南针,到处都没有路,也可以说到处都是路,如何走到终点这是一个很重要的问题。
最后感谢以下大佬的博客:
1.VS2017加装MFC以及创建第一个MFC程序
https://blog.csdn.net/qq_35987486/article/details/94456910
https://blog.csdn.net/qq_39861376/article/details/102678582
2.为什么找不到标志符
https://blog.csdn.net/taotaoah/article/details/46333983
三.判断U盘是否拔出与插入
1.如何进行消息映射
https://blog.csdn.net/eqiang8271/article/details/24477001?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
2.USB GUID
https://blog.csdn.net/phenixyf/article/details/48783271
3.判断U盘插入拔出程序
https://blog.csdn.net/qq_39861376/article/details/102678582
4.各个函数的使用以及导入外部库(windows.h,dbt.h)
MSDN
四.判断U盘容量
lpDirectoryName 是驱动器的名称。
lpFreeBytesAvailableToCaller 是用户可用的磁盘空间。
lpTotalNumberOfBytes 是磁盘总共的空间。
lpTotalNumberOfFreeBytes 是磁盘空闲的空间。以上都是字节为单位。
1.GB与bytes转换:
https://blog.csdn.net/qq_41786318/article/details/80969881
2.获取盘符
忘了记录
3.判断U盘容量程序
https://blog.csdn.net/qq_39861376/article/details/102678582
4.如何用MFC框架生成模态对话框弹出式的程序(跟C#、VB,类似)
鸡啄米http://www.jizhuomi.com/software/160.html
五、复制文件操作
1.copyfile函数的使用
MSDN
https://www.jb51.net/article/190834.htm
2.如何查找文件路径
https://blog.csdn.net/wuhenyouyuyouyu/article/details/78521092
3.string中的replace函数
https://blog.csdn.net/qq_40968179/article/details/104380460
4.Cstring与string之间的相互转换
https://blog.csdn.net/Gordon_Wei/article/details/90443677
5.string如何转换成LPCTSTR类型
https://www.cnblogs.com/qinguoyi/p/7249561.html?utm_source=itdadao&utm_medium=referral
六、删除U盘上的文件
1.deleteFile函数等使用
MSDN
七、停止U盘的使用与终止U盘的使用
如何通过注册表禁用U盘
https://jingyan.baidu.com/article/e2284b2b892cd7e2e6118dbb.html
对注册表的操作
https://www.cnblogs.com/zhaoyixiang/p/12983823.html
如何修改REG_DWORD类型的start值
https://zhidao.baidu.com/question/1046050784719513299.html
八、尝试读取PCB的信息
VC如何获取当前自身PID:
https://blog.csdn.net/sunnysab/article/details/9367077?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param

MFC使用Windows API实现U盘插拔检测,获取U盘容量,U盘内容移动删除,开启和关闭U盘以及获取盘符相关推荐

  1. linux U盘插拔检测

    因为最终要在tiny210上实现此功能,最终选择了hotplug. http://hi.baidu.com/hdy5200075/item/7751f48647f3d12a100ef3f6这里是hot ...

  2. 教程一:windows api(c mfc vs2017)实现U盘插拔检测,获取U盘容量,U盘内容移动,开启和关闭U盘以及获取盘符等

    c++是大二下学期的专业课,大家可能都学过,这里主要介绍U盘这个小项目要用到没学过的知识.(踩坑合集) U盘完整项目源代码下载地址:https://download.csdn.net/download ...

  3. android u盘挂载监听,Android SD卡及U盘插拔状态监听及内容读取

    本篇是通过系统方法来对sd卡及U盘插拔监听及数据获取,Android盒子端开发,有系统权限,当然,这个比较简单,知道具体方法,可以通过反射来实现. 先贴上效果图: 获取外置存储设备并监听插拔状态 获取 ...

  4. Android SD卡及U盘插拔状态监听和内容读取

    本篇是通过系统方法来对sd卡及U盘插拔监听及数据获取,Android盒子端开发,有系统权限,当然,这个比较简单,知道具体方法,可以通过反射来实现. 先贴上效果图: 获取外置存储设备并监听插拔状态 获取 ...

  5. Python:dbus监控U盘插拔

    本文主要介绍在PyQt5中,使用dbus监控U盘插拔. 测试环境:python3 + dbus + pyqt5 当无法引入dbus.mainloop.pyqt5时,安装对应的包即可: sudo apt ...

  6. VB中简便的检测U盘插拔的方法(DriveListBox)

    我在网上找了很多资料,实现检测U盘插拔的方法基本上都是监测WM_DEVICECHANGE.这种方法不但臃肿,而且效率不高,很容易出错.于是我摸索出了一种新的方法,以下就是实现过程. 首先在窗体中添加一 ...

  7. 耳机驱动调试(插拔检测与按键检测)

    耳机驱动调试(插拔检测与按键检测) 小白一枚,欢各位大佬指出错误 耳机类型判断 三段和四段.欧标和美标 现在许多设备的耳机接口都采用3.5mm的耳机接口,其中终端就是,终端可以兼容三段和四段耳机:三段 ...

  8. mtk充电器插拔检测

    以mt6357 pmic为例,充电器插拔检测和类型检测在mt6357-charger-type.c下完成: 一.首先从pmic的probe开始分析: static int mt6357_charger ...

  9. windows快捷键失效 - 重启无效 - 插拔键盘解决

    被windows快捷键失效问题折磨了很久,快捷键都失效了,包括: windows + e windows + r windows + l 等等,尝试修复注册表,尝试设置"关闭Windows键 ...

最新文章

  1. MLIR算子量化Quantization
  2. hyperopt中文文档:Parallelizing-Evaluations-During-Search-via-MongoDB
  3. 11. 盛最多水的容器 golang
  4. [美团 CodeM 初赛 Round A]最长树链
  5. 史上最经典CAP讲解
  6. 越狱解决iphone4s外放无声音
  7. 梦幻粉色空间手机背景素材,爱梦想的设计师
  8. 苏州科技学院计算机组成原理考试,苏州科技学院计算机组成原理复习提纲.doc...
  9. Visual Studio Code for DBA的介绍
  10. SNS类游戏cache server设计浅析
  11. Centos 7忘记密码,如何重置
  12. win10隐藏桌面功能
  13. 揭密360急速免杀系列教程
  14. 手机刷入面具_【手机改造计划】搞机助手 - 小白刷机必备工具,搞机一条龙:解锁、root、刷面具、刷xposed框架、模块下载安装、自动救砖...
  15. vue实现登录验证码
  16. 编译原理 --- 正规式和有限自动机
  17. 计算机无法复制大文件格式,U盘复制文件电脑提示文件过大无法复制怎么解决?...
  18. 树莓派安装MPlayer播放器
  19. 鸽巢排序Pigeonhole sort
  20. 微型计算机中什么是小随机储存器,随机存取存储器

热门文章

  1. java 发送邮件添加附件,Java实现带附件的邮件发送功能
  2. mac wordcloud 字体设置
  3. 调试MCP2515驱动时遇到的问题 CAN控制器和CAN收发器之间的TX和RX引脚接反,导致无法正常收发数据
  4. 客户主数据知识点总结
  5. VMware Workstation 与 Device/Credential Guard 不兼容解决方案
  6. win7打不开计算机网络连接,win7电脑网络连接正常打不开网页怎么解决
  7. resulful规范_resultful风格接口
  8. 爬虫+可视化——链家杭州二手房房源信息
  9. 张景明:方剂【方歌】——清热剂
  10. SLCP验厂辅导,工厂进行社会劳工整合项目(SLCP认证)验证的具体步骤