在vc6.0 mfc 环境下新建工程名称FileMonitor 的MFC Appwizard(exe) 对话框,添加一个启动监控按钮,一个关闭监控按钮。ftp服务器ip 192.168.3.100 匿名身份验证物理路径 d:\FTPRoot 被监控电脑上被监控文件夹是d:\1。点击启动监控按钮时,当被监控电脑上被监控文件夹d:\1下文件更新时将这些文件以相同的文件名实时传输到FTP服务器根目录,点击关闭监控按钮时关闭文件实时传送。
StdAfx.h
// stdafx.h : include file for standard system include files,// or project specific include files that are used frequently, but// are changed infrequently//#if!defined(AFX_STDAFX_H__2915B623_03D7_4EF3_AA50_5A27DB889CDB__INCLUDED_)#defineAFX_STDAFX_H__2915B623_03D7_4EF3_AA50_5A27DB889CDB__INCLUDED_#defineWINVER0x0500#define_WIN32_WINNT0x0500#if_MSC_VER>1000#pragmaonce#endif// _MSC_VER > 1000#defineVC_EXTRALEAN// Exclude rarely-used stuff from Windows headers#include<afxwin.h>// MFC core and standard components#include<afxext.h>// MFC extensions#include<afxdisp.h>// MFC Automation classes#include<afxdtctl.h>// MFC support for Internet Explorer 4 Common Controls#ifndef_AFX_NO_AFXCMN_SUPPORT#include<afxcmn.h>// MFC support for Windows Common Controls#endif// _AFX_NO_AFXCMN_SUPPORT//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_STDAFX_H__2915B623_03D7_4EF3_AA50_5A27DB889CDB__INCLUDED_)FileMonitorDlg.h
// FileMonitorDlg.h : header file//#if!defined(AFX_FILEMONITORDLG_H__30A536A0_330D_4CCF_B982_FC311BB3A8FE__INCLUDED_)#defineAFX_FILEMONITORDLG_H__30A536A0_330D_4CCF_B982_FC311BB3A8FE__INCLUDED_#if_MSC_VER>1000#pragmaonce#endif// _MSC_VER > 1000/////////////////////////////////////////////////////////////////////////////// CFileMonitorDlg dialog#include<afxinet.h>#include<afxmt.h>classCFileMonitorDlg:publicCDialog{// Constructionpublic:CFileMonitorDlg(CWnd*pParent=NULL);// standard constructorstaticUINTMonitorThread(LPVOID pParam);BOOLUploadFileToFTP(constCString&strLocalFile,constCString&strRemoteFile);// Dialog Data//{{AFX_DATA(CFileMonitorDlg)enum{IDD=IDD_FILEMONITOR_DIALOG};CButton m_btnStop;CButton m_btnStart;//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CFileMonitorDlg)protected:virtualvoidDoDataExchange(CDataExchange*pDX);// DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:HICON m_hIcon;CWinThread*m_pMonitorThread;HANDLE m_hStopEvent;CEvent m_StopEvent;BOOL m_bMonitoring;CString m_strLocalPath;CString m_strFTPServer;CString m_strFTPPath;// Generated message map functions//{{AFX_MSG(CFileMonitorDlg)virtualBOOLOnInitDialog();afx_msgvoidOnSysCommand(UINT nID,LPARAM lParam);afx_msgvoidOnPaint();afx_msg HCURSOROnQueryDragIcon();afx_msgvoidOnStartMonitor();afx_msgvoidOnStopMonitor();//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_FILEMONITORDLG_H__30A536A0_330D_4CCF_B982_FC311BB3A8FE__INCLUDED_)FileMonitorDlg.cpp
// FileMonitorDlg.cpp : implementation file//#include"stdafx.h"#include"FileMonitor.h"#include"FileMonitorDlg.h"#include"stdafx.h"#include"FileMonitor.h"#include"FileMonitorDlg.h"#include<io.h>#include<sys/stat.h>#include<afxinet.h>#include<afxmt.h>#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App AboutclassCAboutDlg:publicCDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum{IDD=IDD_ABOUTBOX};//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtualvoidDoDataExchange(CDataExchange*pDX);// DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg():CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}voidCAboutDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CFileMonitorDlg dialogCFileMonitorDlg::CFileMonitorDlg(CWnd*pParent/*=NULL*/):CDialog(CFileMonitorDlg::IDD,pParent){//{{AFX_DATA_INIT(CFileMonitorDlg)// NOTE: the ClassWizard will add member initialization here//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);m_pMonitorThread=NULL;m_bMonitoring=FALSE;m_strLocalPath=_T("d:\\1");m_strFTPServer=_T("192.168.3.100");m_strFTPPath=_T("/");}voidCFileMonitorDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CFileMonitorDlg)DDX_Control(pDX,IDC_STOP_MONITOR,m_btnStop);DDX_Control(pDX,IDC_START_MONITOR,m_btnStart);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CFileMonitorDlg,CDialog)//{{AFX_MSG_MAP(CFileMonitorDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_START_MONITOR,OnStartMonitor)ON_BN_CLICKED(IDC_STOP_MONITOR,OnStopMonitor)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CFileMonitorDlg message handlersBOOLCFileMonitorDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX<0xF000);CMenu*pSysMenu=GetSystemMenu(FALSE);if(pSysMenu!=NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if(!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);}}// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon,TRUE);// Set big iconSetIcon(m_hIcon,FALSE);// Set small icon// TODO: Add extra initialization herem_btnStop.EnableWindow(FALSE);returnTRUE;// return TRUE unless you set the focus to a control}voidCFileMonitorDlg::OnSysCommand(UINT nID,LPARAM lParam){if((nID&0xFFF0)==IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID,lParam);}}// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.voidCFileMonitorDlg::OnPaint(){if(IsIconic()){CPaintDCdc(this);// device context for paintingSendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);// Center icon in client rectangleintcxIcon=GetSystemMetrics(SM_CXICON);intcyIcon=GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);intx=(rect.Width()-cxIcon+1)/2;inty=(rect.Height()-cyIcon+1)/2;// Draw the icondc.DrawIcon(x,y,m_hIcon);}else{CDialog::OnPaint();}}// The system calls this to obtain the cursor to display while the user drags// the minimized window.HCURSORCFileMonitorDlg::OnQueryDragIcon(){return(HCURSOR)m_hIcon;}voidCFileMonitorDlg::OnStartMonitor(){if(m_bMonitoring)return;m_bMonitoring=TRUE;m_StopEvent.ResetEvent();m_btnStart.EnableWindow(FALSE);m_btnStop.EnableWindow(TRUE);m_pMonitorThread=AfxBeginThread(MonitorThread,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);if(m_pMonitorThread){m_pMonitorThread->m_bAutoDelete=FALSE;m_pMonitorThread->ResumeThread();}else{AfxMessageBox(_T("无法创建监控线程!"));m_bMonitoring=FALSE;m_btnStart.EnableWindow(TRUE);m_btnStop.EnableWindow(FALSE);}}voidCFileMonitorDlg::OnStopMonitor(){if(!m_bMonitoring)return;m_bMonitoring=FALSE;m_StopEvent.SetEvent();if(m_pMonitorThread){WaitForSingleObject(m_pMonitorThread->m_hThread,INFINITE);deletem_pMonitorThread;m_pMonitorThread=NULL;}m_btnStart.EnableWindow(TRUE);m_btnStop.EnableWindow(FALSE);}UINTCFileMonitorDlg::MonitorThread(LPVOID pParam){CFileMonitorDlg*pDlg=(CFileMonitorDlg*)pParam;// 确保目录路径以反斜杠结尾CString strDirPath=pDlg->m_strLocalPath;if(strDirPath.Right(1)!=_T("\\"))strDirPath+=_T("\\");HANDLE hDir=CreateFile(strDirPath,FILE_LIST_DIRECTORY,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,NULL);if(hDir==INVALID_HANDLE_VALUE){AfxMessageBox(_T("无法打开监控目录!"));return1;}BYTE buffer[1024];DWORD bytesReturned;OVERLAPPED overlapped;ZeroMemory(&overlapped,sizeof(overlapped));overlapped.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);while(pDlg->m_bMonitoring){ZeroMemory(buffer,sizeof(buffer));bytesReturned=0;if(ReadDirectoryChangesW(hDir,buffer,sizeof(buffer),TRUE,FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_LAST_WRITE,&bytesReturned,&overlapped,NULL)){HANDLE handles[2]={overlapped.hEvent,pDlg->m_StopEvent};DWORD waitResult=WaitForMultipleObjects(2,handles,FALSE,INFINITE);if(waitResult==WAIT_OBJECT_0){FILE_NOTIFY_INFORMATION*pInfo=(FILE_NOTIFY_INFORMATION*)buffer;while(pInfo){if(pInfo->Action==FILE_ACTION_MODIFIED||pInfo->Action==FILE_ACTION_ADDED){CString strFileName;intlen=WideCharToMultiByte(CP_ACP,0,pInfo->FileName,pInfo->FileNameLength/sizeof(WCHAR),NULL,0,NULL,NULL);WideCharToMultiByte(CP_ACP,0,pInfo->FileName,pInfo->FileNameLength/sizeof(WCHAR),strFileName.GetBuffer(len),len,NULL,NULL);strFileName.ReleaseBuffer();CString strFullPath=strDirPath+strFileName;CString strRemoteFile=pDlg->m_strFTPPath+strFileName;pDlg->UploadFileToFTP(strFullPath,strRemoteFile);}if(pInfo->NextEntryOffset==0)break;pInfo=(FILE_NOTIFY_INFORMATION*)((BYTE*)pInfo+pInfo->NextEntryOffset);}}else{break;}}}CloseHandle(overlapped.hEvent);CloseHandle(hDir);return0;}BOOLCFileMonitorDlg::UploadFileToFTP(constCString&strLocalFile,constCString&strRemoteFile){CInternetSessionsession(_T("FileMonitor"));CFtpConnection*pConnection=NULL;try{pConnection=session.GetFtpConnection(m_strFTPServer,_T(""),// 匿名登录_T(""),// 密码为空21,// FTP端口FALSE);// 不使用被动模式if(pConnection){if(!pConnection->PutFile(strLocalFile,strRemoteFile)){AfxMessageBox(_T("文件上传失败!"));pConnection->Close();deletepConnection;session.Close();returnFALSE;}pConnection->Close();deletepConnection;session.Close();returnTRUE;}}catch(CInternetException*pEx){TCHAR szError[1024];pEx->GetErrorMessage(szError,1024);AfxMessageBox(szError);pEx->Delete();if(pConnection){pConnection->Close();deletepConnection;}session.Close();returnFALSE;}returnFALSE;}运行程序