在vc6.0 mfc 环境下新建工程名称FileMonitor 的MFC Appwizard(exe) 对话框,添加一个启动监控按钮,一个关闭监控按钮。ftp服务器ip 192.168.3.100 匿名身份验证物理路径 d:\FTPRoot 被监控电脑上被监控文件夹是d:\1。点击启动监控按钮时,当被监控电脑上被监控文件夹d:\1下文件更新时将这些文件以相同的文件名实时传输到FTP服务器根目录,点击关闭监控按钮时关闭文件实时传送。
StdAfx.h
cpp
// 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_)
#define AFX_STDAFX_H__2915B623_03D7_4EF3_AA50_5A27DB889CDB__INCLUDED_
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_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
cpp
// FileMonitorDlg.h : header file
//
#if !defined(AFX_FILEMONITORDLG_H__30A536A0_330D_4CCF_B982_FC311BB3A8FE__INCLUDED_)
#define AFX_FILEMONITORDLG_H__30A536A0_330D_4CCF_B982_FC311BB3A8FE__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CFileMonitorDlg dialog
#include <afxinet.h>
#include <afxmt.h>
class CFileMonitorDlg : public CDialog
{
// Construction
public:
CFileMonitorDlg(CWnd* pParent = NULL); // standard constructor
static UINT MonitorThread(LPVOID pParam);
BOOL UploadFileToFTP(const CString& strLocalFile, const CString& 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:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
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)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnStartMonitor();
afx_msg void OnStopMonitor();
//}}AFX_MSG
DECLARE_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
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
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::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_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFileMonitorDlg dialog
CFileMonitorDlg::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 Win32
m_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("/");
}
void CFileMonitorDlg::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_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFileMonitorDlg message handlers
BOOL CFileMonitorDlg::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 dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_btnStop.EnableWindow(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CFileMonitorDlg::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.
void CFileMonitorDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.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.
HCURSOR CFileMonitorDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CFileMonitorDlg::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);
}
}
void CFileMonitorDlg::OnStopMonitor()
{
if (!m_bMonitoring)
return;
m_bMonitoring = FALSE;
m_StopEvent.SetEvent();
if (m_pMonitorThread)
{
WaitForSingleObject(m_pMonitorThread->m_hThread, INFINITE);
delete m_pMonitorThread;
m_pMonitorThread = NULL;
}
m_btnStart.EnableWindow(TRUE);
m_btnStop.EnableWindow(FALSE);
}
UINT CFileMonitorDlg::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("无法打开监控目录!"));
return 1;
}
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;
int len = 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);
return 0;
}
BOOL CFileMonitorDlg::UploadFileToFTP(const CString& strLocalFile, const CString& strRemoteFile)
{
CInternetSession session(_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();
delete pConnection;
session.Close();
return FALSE;
}
pConnection->Close();
delete pConnection;
session.Close();
return TRUE;
}
}
catch (CInternetException* pEx)
{
TCHAR szError[1024];
pEx->GetErrorMessage(szError, 1024);
AfxMessageBox(szError);
pEx->Delete();
if (pConnection)
{
pConnection->Close();
delete pConnection;
}
session.Close();
return FALSE;
}
return FALSE;
}
运行程序
