最近整理一些資料,發現之前寫的一段代碼,提供對微軟的版本管理軟件visual sourcesafe的一些操做。如下簡稱vss。html
想起之前寫的時候,由於資料比較匱乏,只能邊研究邊測試,走了很多彎路。數據庫
因爲一些我的的緣由(有點健忘,有點懶),一直沒分享出來。今天趁着有點空,刷刷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;this
額,電腦太垃圾,我就不開vs截圖了。貼下工程文件供參照:spa
<Reference Include="Interop.SourceSafeTypeLib, Version=5.2.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> .net
<HintPath>..\Interop.SourceSafeTypeLib.dll</HintPath> </Reference>orm
具體對vss的操做我都提取在VSSHelper.cs文件中。htm
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); } }