EasyFtp 1.3.2 (适用于应用程序)






4.91/5 (27投票s)
为应用程序提供的“即插即用”FTP解决方案,提供完整图形界面、增强的命令行选项且无资源文件。可独立使用或集成到您自己的应用程序中。
引言
我记得刚开始使用互联网的时候(1993 年,使用 14400 USR Sportster 调制解调器通过 Winsock),感觉不再孤立于电脑之外,是多么令人兴奋。然而,直到大约 10 年后我才真正开始为其编程——没有人说过我能跑之前就得会走!这主要是因为我编写了 ToDoList,一个基于 XML 的任务列表工具,也发布在 CodeProject 上。
我之所以选择 XML 作为数据格式,正是因为它可以在我的网站上上传并通过 JavaScript 处理,更不用说 XSL 转换以及这为报告带来的无数机会了。
然而,我仍然每天是如何进行上传的呢?使用 FTP 工具,这就是答案。
“那又有什么问题呢?”你可能会(也可能不会)问。
从纯粹的功能角度来看,没有任何问题,只是这个过程总让我觉得非常零散:在一个应用程序中保存文档,然后启动一个单独的工具来传输文件,这让我觉得需要彻底改进。
我真正想要的是能够简单地调用类似 GetFile()
的东西(或运行一个独立的应用程序),并且可以选择不带任何参数,然后它能呈现出所有必需的图形界面,让我能够以我过去 8-9 年来已经习惯的方式,即通过类似标准的**打开/保存**对话框,从任何地方获取任何文件。
这就是我在这里所做的尝试。
EasyFtp 是一个不费脑子的实用工具(无意冒犯任何没有脑子的人),它只是包装了一堆执行所有工作的类。
注意:我将其包装成 EXE 的原因是为了让它能够被 TodoList 的“工具”界面支持。正如我稍后会解释的那样,通过将类直接放入您自己的应用程序中,同样可以轻松地使用它。
要求
我之前已经提到了一些要求,但这里有一个更详尽的列表:
- 视觉上直观且熟悉。
- 无需编辑配置。
- 无缝集成。
- 无 RC 文件资源(特别是当它要被集成到多个应用程序时)。
- 完全免费(始终)。
- 轻量级(不过,它是 MFC,一切都是相对的)。
- 可配置——即,我可以传递尽可能多或少的信息,其余的将由我来请求。
设计
我设想的基本工作流程是:
-
上传文件
- 显示标准“打开”对话框以选择要上传的本地文件。
- 显示“服务器详细信息”对话框以获取服务器名称、用户名和密码。
- 登录服务器并显示远程“另存为”对话框以获取要上传的远程文件路径。
- 在上传过程中显示进度/取消对话框。
注意:这些数字直接对应于上面的图像编号。
-
下载文件
- 显示“服务器详细信息”对话框以获取服务器名称、用户名和密码。
- 登录服务器并显示远程“打开”对话框以获取要下载的远程文件路径。
- 显示标准“另存为”对话框以选择要保存的本地文件。
- 在下载过程中显示进度/取消对话框。
听起来很简单,不是吗?
它的妙处在于它就像看起来一样简单,考虑到(我一直如此)我已经为其他项目编写了许多必要的代码。
这里涉及的代码是 CRuntimeDlg
,我最初在 ToDoList 中介绍它,用于在不使用 RC 编辑器和由此产生的 RC 对话框模板依赖的情况下构建对话框。
注意:如果您不清楚为什么这是一个重要的问题,请考虑如果您想重用依赖于对话框资源的代码,需要发生什么。
- 复制/包含 .h/.cpp 文件。
- 从 .RC 文件中复制对话框资源。
- 验证 Visual Studio 在尝试合并新资源时没有产生任何棘手的 resource.h 问题。
相反,CRuntimeDlg
允许您将对话框控件定义嵌入到对话框的 .cpp 文件中,而无需其他任何繁琐的操作。
任何控件(目前可能除了 ActiveX)都能在 Visual Studio 的资源编辑器中放置,也能在 CRuntimeDlg
对话框中使用。
这一切加起来,使得可以毫不犹豫地将文件移动到任何地方——对我来说每次都管用。
实现
这是一个相当简化的图,显示了主要的类关系。
{{DIAGRAM_START
: EasyFtp Class Diagram
.------------.
|CEasyFtpApp |
| |
|Application |
|class |
.v-----------·
|uses
|
.-v---------------.
|CRemoteFile |
| |
|Orchestrates the |
|GUI and does the |
|uploading and |
---< downloading >--------
| ·-v---------------· |
uses| |uses |uses
| | |
.--------------v v------------------. v--------------------.
|CServerDialog | |CRemoteFileDialog | |CProgressDlg |
| | | | | |
|Retrieves the | |Remote version of | |Shows dload/uload |
|server details| |CFileDialog | |progress and doubles|
| | | | | as a cancel dialog |
·-------------v· ·v-----------------· ·v-------------------·
| | |
derived| |derived |derived
from| |from |from
------>v-----------------<------
|CRuntimeDlg |
| |
|Implements dialogs|
| without resource |
|templates |
| |
·------------------·
}}DIAGRAM_END
(由 CodePlotter © AbstractSpoon 2003 绘制)
其余代码包含实用程序类,其中最有趣的是:
CDeferWndMove
对
::DeferWindowPos()
的封装,提供了OffsetCtrl()
和ResizeCtrl()
等便捷功能。CDlgUnits
对
::MapDialogRect()
的封装,提供了重载,用于将 short、int、long、POINT、SIZE 和 RECT 在像素和对话框单位(DLUs)之间进行转换。CSysImageList
对 Windows 系统图像列表(提供文件图标访问)的封装。
CFileEdit
CEdit
的派生类,提供集成的浏览功能,并使用增大的非客户端边框来绘制文件的图标。
使用 EasyFtp(该工具)
默认情况下,即没有命令行参数,EasyFtp 将默认为“下载”模式,并遵循文章中概述的工作流程。
但是,可以使用以下命令行开关来简化或修改这些默认设置(注意:开关必须以 - 或 / 开头)
- up
指定您要上传文件,如果命令行上没有其他内容,这将显示文章图片中的工作流程。
- rp
指定要上传或下载的远程路径。可以是完整路径(不含服务器部分)或仅文件夹,如果是文件夹,则需要以正斜杠结尾。
- lp
指定要上传或下载的本地路径。可以是完整路径或文件夹(无需反斜杠结尾)。
- ag
指定要使用的代理字符串(当 EasyFtp 由另一个应用程序生成时很有用)。
- sv
指定服务器位置,例如 www.microsoft.com。
- us
指定用户名,如果未指定,则执行匿名登录。
- pw
指定账户的密码,如果用户名为空,则密码也可以为空。
- an
指定匿名登录,传递空的用户名/密码字符串。
- nl
指定上传时_不_将文件名转换为小写。
- nc
指定抑制“确认覆盖”对话框,该对话框在上传或下载目标路径已存在时出现。
使用代码
如果您更愿意将代码直接集成到您自己的应用程序中,那么同样也很容易。
- 从(zip 文件中的)shared 文件夹中获取所有文件,并将它们复制到您想要的任何一个位置。
- 在您想要具有 FTP 支持的文件中,添加行
#include "[path]\remotefile.h"
- 最后,在任何您想下载或上传文件的地方,按如下方式添加代码:
// note: this is straight out of EasyFtp.cpp // uploading a file (downloading is almost identical) // sLocalPath and sRemotePath will contain the user's // choice on exit // or simply "rf.SetFile()" RMERR nErr = rf.SetFile(sLocalPath, sRemotePath); // error handling switch (nErr) { case RMERR_SUCCESS: // note: if downloading we would now // do something with the downloaded // file pointed to by sLocalPath break; case RMERR_USERCANCELLED: break; default: { CString sMessage; if (sLocalPath.IsEmpty()) sMessage.Format("Sorry, the requested upload to '%s' could not / be completed for the following reason:\n\n%s", sServer, rf.GetLastError()); else sMessage.Format("Sorry, the upload of '%s' to '%s' could not / be completed for the following reason:\n\n%s", sLocalPath, sServer, rf.GetLastError()); AfxMessageBox(sMessage, MB_OK | MB_ICONEXCLAMATION); } break; }
历史
- 1.0 - 2004 年 2 月 25 日
- 初始发布。
- 1.0.1 - 2004 年 2 月 26 日
- 修复了在取消文件打开对话框后服务器对话框仍然弹出的 bug(仅限上传)。
- 修复了与未正确初始化传递给文件打开对话框的文件名缓冲区相关的崩溃 bug。
- 1.0.2 - 2004 年 2 月 26 日
- 修复了当已指定本地路径时,“另存为”对话框仍然出现的 bug。
- 添加了 'nl' 开关以*阻止*远程上传路径名被转换为小写。
- 1.1 - 2004 年 3 月 10 日
- 增加了对拖放应用程序图标(在资源管理器中或桌面上)的支持。注意:这意味着一旦您设置了指向 FTP 服务器的应用程序命令行,就可以从桌面进行拖放上传。
- 现在可以一次上传或下载多个文件。
- 修复了各种与 UI 相关的 bug。
- 1.3 - 2004 年 3 月 23 日(不确定 1.2 发生了什么)
- 修复了许多 bug。
- 增加了匿名登录。(可以使用 -an 命令行开关进行初始化。)
- 如果上传或下载的目标文件已存在,则添加了确认对话框。(可以使用 -nc 开关禁用。)
- 改进了错误报告,尽管我尚未翻译 HTTP 错误。
- 1.3.1 2004 年 3 月 25 日
- 将 uxtheme.h/tmschema.h 添加到源代码中(感谢 Jay.ca)。
- 1.3.2 2004 年 3 月 27 日
- 将 schemadef.h 添加到源代码中(感谢 Adnan)。