65.9K
CodeProject 正在变化。 阅读更多。
Home

Bitsup - 使用 BITS 的服务器上传实用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (19投票s)

2005年6月26日

6分钟阅读

viewsIcon

99043

downloadIcon

674

一个使用 BITS 作为传输引擎的文件上传实用程序。

引言

Bitsup (Bits Up) 是一款旨在将数据从生产服务器自动传输到备份服务器的程序。该程序使用 Microsoft Windows 的 BITS 服务来执行文件或目录的传输。该程序是命令行驱动的,设计用于通过任务计划程序、批处理文件或脚本运行。

Bitsup 程序会在 Microsoft Windows BITS 服务中创建一个上传作业。然后,它会压缩要传输的数据,将压缩后的文件或目录添加到上传作业中,然后启动该作业。此时,BITS 服务将接管并负责将文件传输到服务器。

Bitsup 程序将监视传输并显示进度条,或者可以设置为“即时发送并忽略”(Fire And Forget) 该作业;将作业提交给 BITS,然后退出。有一个 /Admin 开关,可以以管理员模式启动 Bitsup,该模式会显示传输队列中的所有作业,并允许取消、暂停、恢复或完成作业。

背景

BITS

后台智能传输服务 (BITS) 是 Windows 的一项组件,它可以异步地在前台或后台传输文件,限制传输速度以保持其他网络应用程序的响应能力,并在计算机重新启动并重新建立网络连接时自动恢复文件传输。

我认为 BITS 的一个优点是它扩展了 HTTP 协议以传输文件,并且由于它使用端口 80,因此通常不受防火墙限制。还有一个重要事实是,BITS 的默认设置是尝试发送文件 14 天!

MSDN 上的 BITS 入门页面.

BITSAdmin

BITSAdmin 是一个命令行工具,您可以使用它来创建下载或上传作业并监视其进度。Bitsup 主要是一个“BITSAdmin 包装器”实用程序。由于 BITS API 是老式的 COM,我对此已厌倦,感谢您的询问,我决定最快的方法来接口 BITS 就是包装 BITSAdmin 工具。

MSDN 上的 BITSAdmin 下载页面.

Zip 文件压缩

Bitsup 使用 Sharp Zip Library,一个开源的 C# 压缩库。该压缩引擎支持 ZIP、GZIP、BZIP2 和 TAR 格式。对于 Bitsup 程序,使用的是 ZIP 格式进行压缩。压缩级别可以设置为 0 到 9。压缩值为 0 将只是将文件/目录未压缩地存储在 zip 文件中。压缩值为 9 将实现最大压缩,但创建 zip 文件存档需要更长的时间。默认值为 6,可以通过使用记事本等文本编辑器编辑 Bitsup.exe.config 文件来更改。

我在网上找到了一个不错的 C# 类来包装 SharpZipLib,并将其转换为 VB.NET 用于此项目。我在该类中添加了一些事件,以便在 Windows 窗体对话框中显示进度条。我还公开了一个属性来设置 zip 文件的压缩级别。

    Public Event FileProcessed(ByVal sFileName As String, _
                                      ByVal iPercent As Integer)
    Public Event DirProcessed(ByVal sDirName As String, _
                                      ByVal iPercent As Integer)
    Public Event ZipComplete()
    Public Event ZipStarted()

压缩进度对话框

Sharp Zip Library 主页

使用代码

Bitsup 的核心是 cShell 类,它提供了一个共享方法 (GetProcessText()) 用于调用进程并获取被调用进程的输出。Bitsup 使用 GetProcessText() 来包装 BITSAdmin 命令行工具,并提供图形用户界面。

Public Class cShell
    Public Shared Function GetProcessText(ByVal process As String, _
                                          ByVal param As String, _
                                          ByVal workingDir As String) _
                                          As String
        Dim p As Process = New Process
        ' this is the name of the process we want to execute 
        p.StartInfo.FileName = process
        If Not (workingDir = "") Then
            p.StartInfo.WorkingDirectory = workingDir
        End If
        p.StartInfo.Arguments = param
        ' need to set this to false to redirect output
        p.StartInfo.UseShellExecute = False
        p.StartInfo.RedirectStandardOutput = True
        p.StartInfo.CreateNoWindow = True
        ' start the process 
        p.Start()
        ' read all the output
        ' here we could just read line by line and display it
        ' in an output window 
        Dim output As String = p.StandardOutput.ReadToEnd
        ' wait for the process to terminate 
        p.WaitForExit()
        Return output
    End Function
End Class

命令行界面

Bitsup 使用命令行界面。如果 Bitsup 在没有命令行参数的情况下启动,将显示帮助屏幕,显示可用的选项。

在屏幕顶部将显示命令行解析过程中遇到的错误。

帮助屏幕

命令行格式

bitsup /MODE [/TYPE] [filename|directory]

MODE = RESET | ADMIN | TRANSFER

TYPE = FILE | DIRECTORY

操作模式

Bitsup 共有三种基本“操作模式”。MODE 参数告诉 Bitsup 以哪种模式启动。MODE 参数必须以正斜杠 (/) 开头。MODE 参数的有效值为 RESETADMINTRANSFER

RESET 模式参数会导致 Bitsup 清除传输队列中的所有传输作业。这将停止所有正在进行的上传。

ADMIN 模式参数将显示当前传输队列中所有作业的列表。每个作业都会显示作业 ID、作业名称、作业状态、已传输文件数、总文件数、已传输字节数、总字节数。

TRANSFER 模式参数会导致 Bitsup 将数据传输到服务器。如果使用 TRANSFER 模式,则下一个参数必须是 TYPE 参数,该参数告诉 Bitsup 执行哪种类型的传输。

传输类型

如果 MODE 参数设置为 TRANSFER,则 TYPE 参数必须设置为传输类型。Bitsup 被设计成可扩展到 FILESDIRECTORIES 以外的其他数据类型。在我工作的地方,有几个系统需要定期备份到异地。我设计 Bitsup 来处理这项任务。在此代码库中,我已剥离了其他特定于系统的传输类型。

添加自定义传输类型是一个简单的练习。仔细想想,我本应该创建一个可继承的 cTranferType 对象,并将 FILEDIRECTORY 传输继承下来。也许在 2.0 版本中会实现。毕竟,我是在一个晚上写完这个的。

FILE 传输类型指定单个文件的传输。下一个参数将是文件的完整路径,包括驱动器号。该文件将被压缩并传输到服务器。

DIRECTORY 传输类型指定 Bitsup 应压缩目录及其所有子目录的内容,并将压缩存档传输到服务器。

关注点

我创建此页面的 CodeProject 模板文件提出了以下问题:

在编写代码的过程中,您学到了什么有趣/好笑/令人烦恼的事情吗?您有没有做什么特别聪明、疯狂或异想天开的事情?

思考这个问题时,我确实想到了一件事。我发现 Process 对象在 Bitsup 通过快捷方式启动时,在获取程序标准输出流的句柄方面存在问题。解决方案是创建一个调用 Bitsup 的批处理文件,然后从快捷方式启动该批处理文件。

Dim p As Process = New Process

同样有趣的是,至少对我来说,我是在一个晚上写完 Bitsup 的。之后我想到了一些可以改进的地方,但我不确定改进 Bitsup 的时间是否能更好地用于创建 BITS API 的真正包装器。目前,Bitsup 可以完成它应该做的事情,即使用 BITS 服务传输文件。

历史

  • 2005/6/25:发布到 CodeProject。
© . All rights reserved.