一个根据 Excel 迁移计划从 Visual SouceSafe 获取发布源的应用程序






4.25/5 (8投票s)
如何开发一个应用程序,基于 Excel 迁移计划从 Visual SourceSafe 获取发布源。
引言
一些公司使用迁移计划作为项目发布的依据。迁移计划(通常是 Excel 文件)包含发布文件的详细信息,如发布文件名、路径以及源控制中的版本号。迁移计划中的每个工作表都包含一种类型的发布源信息的条目(即 C++ 工作表包含 .cpp 信息,EXEDLL 工作表包含发布的可执行文件信息)。请看下面的示例迁移计划。
通常,开发完成后,开发人员会更新迁移计划。基于此发布迁移计划,构建工程师可以从源控制中获取源文件并构建源文件以创建安装包,或者仅获取可执行文件(如果源控制包含已正确构建的可执行文件)并创建安装包。
为了在这种情况下自动化项目发布过程,我尝试开发一个 Windows 应用程序,该应用程序可以基于 Excel 迁移计划自动从 Visual SourceSafe 获取源文件。
这是该应用程序的用户界面
用户将输入 VSS 详细信息(如用户名、密码和 INI 文件)、Excel 迁移文件路径以及目标文件夹(将从 VSS 复制文件的位置)。在此应用程序中,用户可以选择获取所有源文件或指定工作表中的文件(在“提取文件”分组框下)。
构建应用程序
首先创建一个新的 Windows 应用程序项目
设计用户界面,如下所示,并为控件命名。
点击“获取文件”按钮时
- 项目将打开迁移文件(Excel 文件)并获取文件详细信息(文件名、路径和版本号)。
- 将文件从 Visual SourceSafe 复制到目标文件夹。
我们将创建一个类来处理 Excel 操作,例如打开 Excel 文件、关闭 Excel 文件以及从各个工作表中获取文件详细信息(即文件路径、文件名以及 VSS 中的版本号)。
我们将创建另一个类来处理 VSS 操作,例如打开 VSS 数据库、关闭 VSS 数据库以及将文件从 VSS 提取到本地系统。
我们可以准备两个独立的组件来处理上述情况。为了使应用程序简单化,我将这两个类都放在了应用程序本身。
要从 Excel 迁移文件中提取文件详细信息,请创建一个新接口(IMigrationFile
),其中包含三个方法:一个用于打开迁移文件的打开方法,一个用于关闭迁移文件的关闭方法,以及一个用于根据工作表名称获取文件详细信息的获取方法。
/// <summary>
/// Interface for Migration File
/// </summary>
interface IMigrationFile
{
//Open the migration file
string OpenMigrationFile(string strMigrationFile);
//Close the migration file
string CloseMigrationFile();
// Get the file details(File Name,Path
// and Version No) for the input work sheet
ArrayList GetFileDetails(string strWorkSheet);
};
通过“项目”->“添加新项”将一个新类(ExclMigrationFile.cs)添加到项目中。此类将实现 IMigrationFile
接口。
要访问 Excel 自动化方法,我们需要通过“项目”->“添加引用”下的 COM 选项卡添加对 Excel 对象的引用。
每个工作表包含文件路径、文件名和版本号。创建一种结构来存储这些值,以便在从工作表中提取它们时使用。
/// <summary>
/// Structure to hold file details (File Path,File Name and Version No)
/// </summary>
public struct FileDetails
{
public string FilePath;
public string FileName;
public int VersionNo;
};
现在,我们需要为 IMigrationFile
接口方法提供实现。在实现这些接口方法之前,请将以下 private
变量添加到类中。
private ExclVSS._Application exclVSSApp=null;
private ExclVSS.Sheets exclVSSWorkSheets=null;
现在提供 OpenMigrationFile
方法的实现。
/// <summary>
/// Open the Excel Migration File .
/// </summary>
/// <summary>
public string OpenMigrationFile(string strMigrationFile)
{
try
{
//Create the Excel Application Class
this.ExclApp= new Microsoft.Office.Interop.Excel.ApplicationClass();
//Open the Excel file
this.ExclApp.Workbooks.Open(strMigrationFile,vk_update_links,
vk_read_only, vk_format, vk_password,vk_write_res_password,
vk_ignore_read_only_recommend, vk_origin,vk_delimiter,
vk_editable, vk_notify, vk_converter,
vk_add_to_mru,vk_local, vk_corrupt_load);
//Get the Excel work sheet
this.ExclWorkSheets=this.ExclApp.Worksheets;
}
catch(Exception e)
{
return e.ToString();
}
return "";
}
接下来,我们提供 CloseMigrationFile
方法的实现。
/// <summary>
/// Close the Excel Migration File .
/// </summary>
public string CloseMigrationFile()
{
try
{
//Close the Work Books
this.ExclApp.Workbooks.Close();
}
catch(Exception e)
{
return e.ToString();
}
return "";
}
现在需要实现第三个接口方法 GetFileDetails
。此方法从用户选择的工作表中提取文件详细信息。此方法使用一个辅助函数(GetFileDetails
)来提取文件详细信息。
/// <summary>
/// Get the file details for the given work sheet .
/// </summary>
public ArrayList GetFileDetails(string strWorkSheet)
{
//Create an ArrayList to hold the File Details
//(File Path,Name and Version NO)
ArrayList alFileList=new ArrayList();
//Iterate the Worksheets to get the C++ files Worksheet
foreach(Excl.Worksheet exclWorkSheet in exclWorkSheets)
{
//Check if Worksheet name and the user choice are same
if(strWorkSheet == exclWorkSheet.Name)
{
//Get File Details
GetFileDetails(exclWorkSheet, ref alFileList);
break;
}
}
//Return the array list to the client
return alFileList;
}
/// <summary>
/// This is a helper function to extract the file names
/// and their paths based on the input work sheet
/// </summary>
private void GetFileDetails(Excl.Worksheet exclWorkSheet,
ref ArrayList alFileDetails)
{
//Activate the work sheet
exclWorkSheet.Activate();
//Get the number of rows
int nRowCount=exclWorkSheet.UsedRange.EntireRow.Count;
for(int i=2;i<=nRowCount;i++)
{
//Get the file names and their paths from the sheet
// Column : A contains File Path
//Column : B contains File Name
Excl.Range rangeCPP=exclWorkSheet.get_Range("A"+i.ToString(),
"C" + i.ToString());
//Get the file path and names for the row
System.Array array = (System.Array)rangeCPP.Cells.Value2;
//Create File Details object
FileDetails fileDetails=new FileDetails();
//Get the File Path
fileDetails.FilePath=(string)array.GetValue(1,1).ToString();
//Get the File Name
fileDetails.FileName=(string)array.GetValue(1,2).ToString();
//Get the Version No
fileDetails.VersionNo=
Convert.ToInt32(array.GetValue(1,3).ToString());
//Add to the ArrayList
alFileDetails.Add(fileDetails);
}
}
要从 VSS 获取文件,请创建一个新接口(ISourceControl
),其中包含三个方法:打开 VSS 数据库的方法、关闭 VSS 数据库的方法以及从 VSS 获取指定文件的方法。
/// <summary>
/// Interface for Source Control
/// </summary>
interface ISourceControl
{
//Open the SourceSafe
string OpenSourceControl(string UserName,
string Password, string INIPath);
//Close the SourceSafe
string CloseSourceControl();
//Get the specified version file
string GetFileFromSourceControl(string FilePath,
string DestinationPath, int VersionNo,int Flags);
};
通过“项目”->“添加新项”将一个新类(VSS.cs)添加到项目中。此类将实现 ISourceControl
接口。
要访问 Visual SourceSafe 自动化方法,我们需要通过“项目”->“添加引用”下的 COM 选项卡添加对 VSS 对象的引用。
现在提供 ISourceControl
接口方法的实现。
//Open the SourceSafe
public string OpenSourceControl(string UserName,
string Password, string INIPath)
{
//Create VSS Database object
vssDatabase = new SourceSafeTypeLib.VSSDatabase();
try
{
//Open the VSS Database based on User Name,
//Passwor and INI file name
vssDatabase.Open (INIPath, UserName, Password);
}
catch(Exception e)
{
return e.ToString();
}
return "";
}
//Close the SourceSafe
public string CloseSourceControl()
{
try
{
//Set VSSDatabase object to null
vssDatabase = null;
}
catch(Exception e)
{
return e.ToString();
}
return "";
}
//Get the specified version file
public string GetFileFromSourceControl(string FilePath,
string DestinationPath,int VersionNo,int Flags)
{
SourceSafeTypeLib.VSSItem vssItem;
SourceSafeTypeLib.VSSItem vssVersionItem;
try
{
/// Get the VSS Item
vssItem = vssDatabase.get_VSSItem(FilePath, false);
//Get the specified verison
vssVersionItem=vssItem.get_Version(VersionNo);
//Extract the file to the destination folder
vssVersionItem.Get(ref DestinationPath, Flags);
}
catch(Exception e)
{
return e.ToString();
}
return "";
}
我们已经完成了 IMigrationFile
和 ISourceControl
的实现。
现在提供 UI 控件处理程序的实现。
“获取文件”按钮的 OnClick
实现。
/// <summary>
/// Get file details from migration file
/// and extract the corresponding files from VSS.
/// </summary>
private void btnGetFiles_Click(object sender, System.EventArgs e)
{
//Initialize Excel and VSS Objects and
//Open the Excel and VSS Database
Initialize_OpenExcelVSS();
//Extract Files
ExtractFiles();
//Close Excel and VSS Database
Close_ExcelVSS();
}
此方法将执行以下操作:
步骤 1
使用 IMigrationFile
和 ISourceControl
接口方法打开 Excel 文件和 VSS 数据库。
/// <summary>
/// Initialize and Open Excel and VSS Database.
/// </summary>
private void Initialize_OpenExcelVSS()
{
//Get the user options
strUserName=txtUserName.Text;
strPwd=txtPwd.Text;
strINIPath=txtIniName.Text;
strExcelPath=txtExcel.Text;
strDestPath=txtDest.Text;
//Create objects
this.iExcel=new AutoMigration.ExcelMigrationFile();
this.iVSS=new AutoMigration.VSS();
//Open Excel file
this.iExcel.OpenMigrationFile(strExcelPath);
//Open VSS Database
this.iVSS.OpenSourceControl(strUserName,strPwd,strINIPath);
}
第二步
从 Excel 工作表中获取文件详细信息(文件路径、文件名和版本号)。
/// <summary>
/// Extract File details from Excel Migration Plan.
/// </summary>
private void ExtractFiles()
{
//C++
if(true==chkCPP.Checked)
{
ArrayList al=null;
//Get the file details from Excel work sheet
al=this.iExcel.GetFileDetails(strCPP);
//Extract the file from VSS to the destination folder
GetVSSFiles(al);
}
//VB
if(true==chkVB.Checked)
{
ArrayList al=null;
//Get the file details from Excel work sheet
al=this.iExcel.GetFileDetails(strVB);
//Extract the file from VSS to the destination folder
GetVSSFiles(al);
}
//XML
if(true==chkXML.Checked)
{
ArrayList al=null;
//Get the file details from Excel work sheet
al=this.iExcel.GetFileDetails(strXML);
//Extract the file from VSS to the destination folder
GetVSSFiles(al);
}
//EXE
if(true==chkEXE.Checked)
{
ArrayList al=null;
//Get the file details from Excel work sheet
al=this.iExcel.GetFileDetails(strEXE);
//Extract the file from VSS to the destination folder
GetVSSFiles(al);
}
//ASP
if(true==chkASP.Checked)
{
ArrayList al=null;
//Get the file details from Excel work sheet
al=this.iExcel.GetFileDetails(strASP);
//Extract the file from VSS to the destination folder
GetVSSFiles(al);
}
}
步骤 3
根据文件路径、名称和版本号(在上一步中获取)从 VSS 中提取文件。
/// <summary>
/// Get specified verion file from VSS .
/// </summary>
private string GetVSSFiles(ArrayList alFiles)
{
string strFilePath;
try
{
//Get the Enumerator for ArrayList
System.Collections.IEnumerator myEnumerator = alFiles.GetEnumerator();
while ( myEnumerator.MoveNext() )
{
//Extract the FileDetails
FileDetails fileDetails=(FileDetails) myEnumerator.Current;
//Get the File Path
strFilePath=fileDetails.FilePath+fileDetails.FileName;
//Get files from VSS
this.iVSS.GetFileFromSourceControl(strFilePath,strDestPath,
fileDetails.VersionNo,Flags);
}
}
catch(Exception e)
{
return e.ToString();
}
return "";
}
步骤 4
关闭 Excel 文件和 VSS 数据库。
/// <summary>
/// Close Excel and VSS Database.
/// </summary>
private void Close_ExcelVSS()
{
//Close Excel
this.iExcel.CloseMigrationFile();
//Close VSS Database
this.iVSS.CloseSourceControl();
this.iExcel=null;
this.iVSS=null;
}
浏览按钮的实现。
/// <summary>
/// Browse INI Files.
/// </summary>
private void btnINI_Click(object sender, System.EventArgs e)
{
//Use Open File Dialog
OpenFileDialog openINIFile = new OpenFileDialog();
//Set the default text as ini, so that
//file open dialog displays only ini files
openINIFile.DefaultExt = "ini";
// The Filter property requires a search string after the pipe ( | )
openINIFile.Filter = "INI Files (*.ini)|*.ini";
openINIFile.ShowDialog();
//Get the INI file
txtExcel.Text=openINIFile.FileName;
}
/// <summary>
/// Browse XLS Files.
/// </summary>
private void btnExcel_Click(object sender, System.EventArgs e)
{
//Use Open File Dialog
OpenFileDialog openExcelFile = new OpenFileDialog();
//Set the default text as xls, so that
//file open dialog displays only Excel files
openExcelFile.DefaultExt = "xls";
// The Filter property requires a search string after the pipe ( | )
openExcelFile.Filter = "Excel sheets (*.xls)|*.xls";
openExcelFile.ShowDialog();
//Get the Excel File
txtExcel.Text=openExcelFile.FileName;
}
这是自动化迁移计划发布过程的第一步。下一步将是自动构建获取的源文件(我将在下一篇文章中介绍此主题)。
在测试应用程序之前,请确保用户具有连接到 Visual SourceSafe 和获取源文件的适当权限。
参考和进一步阅读
MSDN 文档
- Tim Winter。Visual SourceSafe 6.0 自动化。1998 年 9 月。