.net中操作Visual SourceSafe
最近整理一些资料,发现以前写的一段代码,提供对微软的版本管理软件visual sourcesafe的一些操作。以下简称vss。
想起以前写的时候,因为资料比较匮乏,只能边研究边测试,走了不少弯路。
由于一些个人的原因(有点健忘,有点懒),一直没分享出来。今天趁着有点空,刷刷blog。
ps:上一个绘制c语言头文件包含关系图的小工具(http://www.cnblogs.com/geeking/p/4021044.html),不知大家发现没有,bug很多。主要集中在头文件循环引用和大量节点绘制上。(实验发现,绘制大量节点时,TreeGX控件最好visible false。貌似控件添加“可看到”节点时会触发内部刷新操作,而此时又正在添加节点,会引发"System.InvalidOperationException"错误)。新版本v2.0稍后更新。
言归正传。
.net中要对vss操作,要先引用Interop.SourceSafeTypeLib.dll,还有命名空间 using SourceSafeTypeLib;
额,电脑太垃圾,我就不开vs截图了。贴下工程文件供参照:
<Reference Include="Interop.SourceSafeTypeLib, Version=5.2.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion>
<HintPath>..\Interop.SourceSafeTypeLib.dll</HintPath> </Reference>
具体对vss的操作我都提取在VSSHelper.cs文件中。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SourceSafeTypeLib; using System.IO; using System.Windows.Forms; namespace DockSample { public static class VSSHelper { public static string workPath = ""; private static string root = "$/"; private static VSSDatabaseClass db = new VSSDatabaseClass(); /// <summary> /// 检查VSS是否打开,已打开返回true,未打开返回false /// </summary> /// <returns></returns> public static bool checkVSSOpen() { try { //VSS未提供标志是否打开的字段 //故调用get_VSSItem方法,若抛出异常代码-2147210253则证明未打开 //未抛出异常则证明已经打开连接 VSSItem vssItem = db.get_VSSItem(root, false); vssItem = null; return true; } //catch (System.Runtime.InteropServices.COMException comex) //{ // if (comex.ErrorCode == -2147210253) // { // MessageBox.Show("您尚未登录VSS\r\n请登录后重试", "错误"); // } // return false; //} catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return false; } } /// <summary> /// 打开VSS,返回true成功打开,false未成功打开 /// </summary> /// <param name="vssIniPath"></param> /// <param name="user"></param> /// <param name="pwd"></param> /// <returns></returns> public static bool openVSS(string vssIniPath, string user, string pwd) { try { //避免重复打开出错 if (!checkVSSOpen()) { db.Open(vssIniPath, user, pwd); } else { MessageBox.Show("连接已经打开\r\n请勿重复打开", "提示"); } #region 测试用代码: //creatSub(@"F:\ceshi", root); //creat(@"F:\ceshi"); #endregion return true; } catch (System.Runtime.InteropServices.COMException comex) { System.Diagnostics.Debug.WriteLine(comex.Message); return false; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return false; } } #region 弃用 //public static void creat(string parentPath) //{ // //if (workPath == string.Empty) // //{ // // return; // //} // DirectoryInfo dirInfo = new DirectoryInfo(parentPath); // try // { // VSSItem vssItem = db.get_VSSItem(root, false); // vssItem.NewSubproject(dirInfo.Name, "created"); // } // catch (Exception ex) // { // System.Diagnostics.Debug.WriteLine(ex.Message); // } // creatSub(parentPath, root); //} #endregion public static bool creatSub(string path, string vssRoot) { if (Directory.Exists(path)) { DirectoryInfo dirInfo = new DirectoryInfo(path); FileInfo[] fileInfos = dirInfo.GetFiles(); DirectoryInfo[] subDirInfos = dirInfo.GetDirectories(); VSSItem vssItem = db.get_VSSItem(vssRoot, false); //将目录中的所有文件(排除.scc文件)添加到VSS中 foreach (FileInfo fileInfo in fileInfos) { try { if (fileInfo.Extension.ToLower() != ".scc") { //添加本地文件到VSS vssItem.Add(fileInfo.FullName, "add", 0); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return false; } } //使用递归,根据本地目录结构创建VSS工程目录结构 foreach (DirectoryInfo subDirInfo in subDirInfos) { try { //创建VSS子工程(子目录) vssItem.NewSubproject(subDirInfo.Name, "created"); //递归调用,构建当前处理目录的下层目录结构(工程结构) if (!creatSub(subDirInfo.FullName, vssRoot + subDirInfo.Name + "/")) { return false; } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return false; } } return true; } else { MessageBox.Show("目录:" + path + " 不存在", "错误"); return false; } } public static bool checkOut(string vssPath, string localPath) { return exeCMD(vssPath, localPath, "checkout"); #region 舍弃 //try //{ // VSSItem vssitem = db.get_VSSItem(vssPath, false); // //Type==0 项目文件夹,Type==1 项目文件 // //若当前checkout的是单个文件,则checkout后直接返回 // if (vssitem.Type == 1) // { // vssitem.Checkout("checkout", localPath, 0); // return true; // } // //若checkout的是一个目录,则递归目录下的所有文件, // //包括子目录中的文件。并把所有文件checkout // IVSSItems ivssitems = vssitem.get_Items(false); // //防止Path结构错误 // localPath = localPath.EndsWith(@"\") ? localPath : localPath + @"\"; // vssPath = vssPath.EndsWith("/") ? vssPath : vssPath + "/"; // foreach (IVSSItem ivssitem in ivssitems) // { // if (ivssitem.Type == 1) // { // //项目文件,直接checkout // ivssitem.Checkout("checkout", localPath + ivssitem.Name, 0); // } // else if (ivssitem.Type == 0) // { // //项目文件夹,递归调用checkOut函数 // bool temp = checkOut(vssPath + ivssitem.Name, localPath + ivssitem.Name); // if (!temp) // { // return false; // } // } // } // return true; //} //catch (Exception ex) //{ // System.Diagnostics.Debug.WriteLine(ex.Message); // return false; //} #endregion } private static bool exeCMD(string vssPath, string localPath, string cmd) { try { VSSItem vssitem = db.get_VSSItem(vssPath, false); //Type==0 项目文件夹,Type==1 项目文件 if (vssitem.Type == 1) { switch (cmd.ToLower()) { case "checkout": if (vssitem.IsCheckedOut == 0) { vssitem.Checkout(cmd, localPath, 0); return true; } MessageBox.Show("请勿重复CheckOut", "提示"); return false; case "checkin": if (vssitem.IsCheckedOut != 0) { vssitem.Checkin(cmd, localPath, 0); return true; } MessageBox.Show("请先CheckOut", "提示"); return false; case "get": vssitem.Get(ref localPath, 0); return true; default: break; } } IVSSItems ivssitems = vssitem.get_Items(false); //防止Path结构错误 localPath = localPath.EndsWith(@"\") ? localPath : localPath + @"\"; vssPath = vssPath.EndsWith("/") ? vssPath : vssPath + "/"; foreach (IVSSItem ivssitem in ivssitems) { if (ivssitem.Type == 1) //项目文件 { string tmpLocalPath = localPath + ivssitem.Name; switch (cmd.ToLower()) { case "checkout": if (ivssitem.IsCheckedOut == 0) { ivssitem.Checkout(cmd, tmpLocalPath, 0); } break; case "checkin": if (ivssitem.IsCheckedOut != 0) { ivssitem.Checkin(cmd, tmpLocalPath, 0); } break; case "get": ivssitem.Get(ref tmpLocalPath, 0); break; default: break; } } else if (ivssitem.Type == 0) //项目文件夹 { //递归调用checkin函数 bool temp = exeCMD(vssPath + ivssitem.Name, localPath + ivssitem.Name, cmd); if (!temp) { return false; } } } return true; } catch (System.Runtime.InteropServices.COMException comex) { if (comex.ErrorCode == -2147210253) { MessageBox.Show("您尚未登录VSS\r\n请登录后重试", "错误"); FrmVSSLogin frm = new FrmVSSLogin(); frm.ShowDialog(); } return false; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return false; } } public static bool checkIn(string vssPath, string localPath) { return exeCMD(vssPath, localPath, "checkin"); #region 舍弃 //try //{ // VSSItem vssitem = db.get_VSSItem(vssPath, false); // if (vssitem.Type == 1) // { // //IsCheckedOut==0 未checkout // //若被checkout,则checkin // if (vssitem.IsCheckedOut != 0) // { // //vssitem. // vssitem.Checkin("checkin", localPath, 0); // return true; // } // } // IVSSItems ivssitems = vssitem.get_Items(false); // //防止Path结构错误 // localPath = localPath.EndsWith(@"\") ? localPath : localPath + @"\"; // vssPath = vssPath.EndsWith("/") ? vssPath : vssPath + "/"; // foreach (IVSSItem ivssitem in ivssitems) // { // if (ivssitem.Type == 1) // { // if (ivssitem.IsCheckedOut != 0) // { // ivssitem.Checkin("checkin", localPath + ivssitem.Name, 0); // } // } // else if (ivssitem.Type == 0) // { // //项目文件夹,递归调用checkin函数 // bool temp = checkIn(vssPath + ivssitem.Name, localPath + ivssitem.Name); // if (!temp) // { // return false; // } // } // } // return true; //} //catch (Exception ex) //{ // System.Diagnostics.Debug.WriteLine(ex.Message); // return false; //} #endregion } public static bool get(string vssPath, string localPath) { return exeCMD(vssPath, localPath, "get"); } #region 弃用 //public static bool checkOut(string vssPath, string localPath, string selectFileName) //{ // try // { // VSSItem vssitem = db.get_VSSItem(vssPath, false); // IVSSItems ivssitems = vssitem.get_Items(false); // localPath = localPath.EndsWith(@"\") ? localPath : localPath + @"\"; // foreach (IVSSItem ivssitem in ivssitems) // { // if (ivssitem.Name == selectFileName) // { // ivssitem.Checkout("checkout", localPath + ivssitem.Name, 0); // } // } // return true; // } // catch (Exception ex) // { // System.Diagnostics.Debug.WriteLine(ex.Message); // return false; // } //} #endregion } }
private void btnBrowse_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog() { Filter = "VSS配置文件|*.ini", Title = "打开VSS数据库文件" }; if (ofd.ShowDialog() == DialogResult.OK) { tboxVSS.Text = ofd.FileName; } } private void btnLogin_Click(object sender, EventArgs e) { string[] messboxText ={ "VSS打开错误!\r\n请检查配置重试。", "VSS配置文件不存在!" }; if (tboxVSS.Text == "") { return; } if (System.IO.File.Exists(tboxVSS.Text)) { //打开VSS if (VSSHelper.openVSS(tboxVSS.Text, tboxUserName.Text, tboxPassword.Text)) { this.Close(); } else { //if (MessageBox.Show(messboxText[0], "错误", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) != DialogResult.Retry) //{ // this.Close(); //} MessageBox.Show(messboxText[0], "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show(messboxText[1], "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } }