首页 > 代码库 > .net中操作Visual SourceSafe
.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文件中。
以下是具体内容:(哎,发现自己废话越来越多了,莫非有向唐僧发展的节奏么)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using SourceSafeTypeLib; 6 using System.IO; 7 using System.Windows.Forms; 8 namespace DockSample 9 { 10 public static class VSSHelper 11 { 12 public static string workPath = ""; 13 private static string root = "$/"; 14 private static VSSDatabaseClass db = new VSSDatabaseClass(); 15 /// <summary> 16 /// 检查VSS是否打开,已打开返回true,未打开返回false 17 /// </summary> 18 /// <returns></returns> 19 public static bool checkVSSOpen() 20 { 21 try 22 { 23 //VSS未提供标志是否打开的字段 24 //故调用get_VSSItem方法,若抛出异常代码-2147210253则证明未打开 25 //未抛出异常则证明已经打开连接 26 VSSItem vssItem = db.get_VSSItem(root, false); 27 vssItem = null; 28 return true; 29 } 30 //catch (System.Runtime.InteropServices.COMException comex) 31 //{ 32 // if (comex.ErrorCode == -2147210253) 33 // { 34 // MessageBox.Show("您尚未登录VSS\r\n请登录后重试", "错误"); 35 // } 36 // return false; 37 //} 38 catch (Exception ex) 39 { 40 System.Diagnostics.Debug.WriteLine(ex.Message); 41 return false; 42 } 43 } 44 /// <summary> 45 /// 打开VSS,返回true成功打开,false未成功打开 46 /// </summary> 47 /// <param name="vssIniPath"></param> 48 /// <param name="user"></param> 49 /// <param name="pwd"></param> 50 /// <returns></returns> 51 public static bool openVSS(string vssIniPath, string user, string pwd) 52 { 53 try 54 { 55 //避免重复打开出错 56 if (!checkVSSOpen()) 57 { 58 db.Open(vssIniPath, user, pwd); 59 } 60 else 61 { 62 MessageBox.Show("连接已经打开\r\n请勿重复打开", "提示"); 63 } 64 65 66 #region 测试用代码: 67 //creatSub(@"F:\ceshi", root); 68 //creat(@"F:\ceshi"); 69 #endregion 70 return true; 71 } 72 catch (System.Runtime.InteropServices.COMException comex) 73 { 74 System.Diagnostics.Debug.WriteLine(comex.Message); 75 return false; 76 } 77 catch (Exception ex) 78 { 79 System.Diagnostics.Debug.WriteLine(ex.Message); 80 return false; 81 } 82 } 83 #region 弃用 84 //public static void creat(string parentPath) 85 //{ 86 // //if (workPath == string.Empty) 87 // //{ 88 // // return; 89 // //} 90 // DirectoryInfo dirInfo = new DirectoryInfo(parentPath); 91 // try 92 // { 93 // VSSItem vssItem = db.get_VSSItem(root, false); 94 // vssItem.NewSubproject(dirInfo.Name, "created"); 95 // } 96 // catch (Exception ex) 97 // { 98 // System.Diagnostics.Debug.WriteLine(ex.Message); 99 // }100 // creatSub(parentPath, root);101 102 //}103 #endregion104 public static bool creatSub(string path, string vssRoot)105 {106 if (Directory.Exists(path))107 {108 DirectoryInfo dirInfo = new DirectoryInfo(path);109 FileInfo[] fileInfos = dirInfo.GetFiles();110 DirectoryInfo[] subDirInfos = dirInfo.GetDirectories();111 VSSItem vssItem = db.get_VSSItem(vssRoot, false);112 //将目录中的所有文件(排除.scc文件)添加到VSS中113 foreach (FileInfo fileInfo in fileInfos)114 {115 try116 {117 if (fileInfo.Extension.ToLower() != ".scc")118 {119 //添加本地文件到VSS120 vssItem.Add(fileInfo.FullName, "add", 0);121 }122 123 }124 catch (Exception ex)125 {126 System.Diagnostics.Debug.WriteLine(ex.Message);127 return false;128 }129 }130 //使用递归,根据本地目录结构创建VSS工程目录结构131 foreach (DirectoryInfo subDirInfo in subDirInfos)132 {133 try134 {135 //创建VSS子工程(子目录)136 vssItem.NewSubproject(subDirInfo.Name, "created");137 //递归调用,构建当前处理目录的下层目录结构(工程结构)138 if (!creatSub(subDirInfo.FullName, vssRoot + subDirInfo.Name + "/"))139 {140 return false;141 }142 }143 catch (Exception ex)144 {145 System.Diagnostics.Debug.WriteLine(ex.Message);146 return false;147 }148 }149 return true;150 }151 else152 {153 MessageBox.Show("目录:" + path + " 不存在", "错误");154 return false;155 }156 }157 public static bool checkOut(string vssPath, string localPath)158 {159 return exeCMD(vssPath, localPath, "checkout");160 #region 舍弃161 //try162 //{163 // VSSItem vssitem = db.get_VSSItem(vssPath, false);164 // //Type==0 项目文件夹,Type==1 项目文件165 // //若当前checkout的是单个文件,则checkout后直接返回166 // if (vssitem.Type == 1)167 // {168 // vssitem.Checkout("checkout", localPath, 0);169 // return true;170 // }171 // //若checkout的是一个目录,则递归目录下的所有文件,172 // //包括子目录中的文件。并把所有文件checkout173 // IVSSItems ivssitems = vssitem.get_Items(false);174 // //防止Path结构错误175 // localPath = localPath.EndsWith(@"\") ? localPath : localPath + @"\";176 // vssPath = vssPath.EndsWith("/") ? vssPath : vssPath + "/";177 // foreach (IVSSItem ivssitem in ivssitems)178 // {179 // if (ivssitem.Type == 1)180 // {181 // //项目文件,直接checkout182 // ivssitem.Checkout("checkout", localPath + ivssitem.Name, 0);183 // }184 // else if (ivssitem.Type == 0)185 // {186 // //项目文件夹,递归调用checkOut函数187 // bool temp = checkOut(vssPath + ivssitem.Name, localPath + ivssitem.Name);188 // if (!temp)189 // {190 // return false;191 // }192 // }193 194 // }195 // return true;196 //}197 //catch (Exception ex)198 //{199 // System.Diagnostics.Debug.WriteLine(ex.Message);200 // return false;201 //} 202 #endregion203 }204 private static bool exeCMD(string vssPath, string localPath, string cmd)205 {206 try207 {208 VSSItem vssitem = db.get_VSSItem(vssPath, false);209 //Type==0 项目文件夹,Type==1 项目文件210 if (vssitem.Type == 1)211 {212 switch (cmd.ToLower())213 {214 case "checkout":215 if (vssitem.IsCheckedOut == 0)216 {217 vssitem.Checkout(cmd, localPath, 0);218 return true;219 }220 MessageBox.Show("请勿重复CheckOut", "提示");221 return false;222 case "checkin":223 if (vssitem.IsCheckedOut != 0)224 {225 vssitem.Checkin(cmd, localPath, 0);226 return true;227 }228 MessageBox.Show("请先CheckOut", "提示");229 return false;230 case "get":231 vssitem.Get(ref localPath, 0);232 return true;233 default:234 break;235 }236 237 }238 IVSSItems ivssitems = vssitem.get_Items(false);239 //防止Path结构错误240 localPath = localPath.EndsWith(@"\") ? localPath : localPath + @"\";241 vssPath = vssPath.EndsWith("/") ? vssPath : vssPath + "/";242 foreach (IVSSItem ivssitem in ivssitems)243 {244 if (ivssitem.Type == 1) //项目文件245 {246 string tmpLocalPath = localPath + ivssitem.Name;247 switch (cmd.ToLower())248 {249 case "checkout":250 if (ivssitem.IsCheckedOut == 0)251 {252 ivssitem.Checkout(cmd, tmpLocalPath, 0);253 }254 break;255 case "checkin":256 if (ivssitem.IsCheckedOut != 0)257 {258 ivssitem.Checkin(cmd, tmpLocalPath, 0);259 }260 break;261 case "get":262 ivssitem.Get(ref tmpLocalPath, 0);263 break;264 default:265 break;266 }267 }268 else if (ivssitem.Type == 0) //项目文件夹269 {270 //递归调用checkin函数271 bool temp = exeCMD(vssPath + ivssitem.Name, localPath + ivssitem.Name, cmd);272 if (!temp)273 {274 return false;275 }276 }277 278 }279 return true;280 }281 catch (System.Runtime.InteropServices.COMException comex)282 {283 if (comex.ErrorCode == -2147210253)284 {285 MessageBox.Show("您尚未登录VSS\r\n请登录后重试", "错误");286 FrmVSSLogin frm = new FrmVSSLogin();287 frm.ShowDialog();288 }289 return false;290 }291 catch (Exception ex)292 {293 System.Diagnostics.Debug.WriteLine(ex.Message);294 return false;295 }296 }297 public static bool checkIn(string vssPath, string localPath)298 {299 return exeCMD(vssPath, localPath, "checkin");300 #region 舍弃301 //try302 //{303 // VSSItem vssitem = db.get_VSSItem(vssPath, false);304 // if (vssitem.Type == 1)305 // {306 // //IsCheckedOut==0 未checkout307 // //若被checkout,则checkin308 // if (vssitem.IsCheckedOut != 0)309 // {310 // //vssitem.311 // vssitem.Checkin("checkin", localPath, 0);312 // return true;313 // }314 // }315 // IVSSItems ivssitems = vssitem.get_Items(false);316 // //防止Path结构错误317 // localPath = localPath.EndsWith(@"\") ? localPath : localPath + @"\";318 // vssPath = vssPath.EndsWith("/") ? vssPath : vssPath + "/";319 // foreach (IVSSItem ivssitem in ivssitems)320 // {321 // if (ivssitem.Type == 1)322 // {323 // if (ivssitem.IsCheckedOut != 0)324 // {325 // ivssitem.Checkin("checkin", localPath + ivssitem.Name, 0);326 // }327 328 // }329 // else if (ivssitem.Type == 0)330 // {331 // //项目文件夹,递归调用checkin函数332 // bool temp = checkIn(vssPath + ivssitem.Name, localPath + ivssitem.Name);333 // if (!temp)334 // {335 // return false;336 // }337 // }338 339 // }340 // return true;341 //}342 //catch (Exception ex)343 //{344 // System.Diagnostics.Debug.WriteLine(ex.Message);345 // return false;346 //} 347 #endregion348 }349 public static bool get(string vssPath, string localPath)350 {351 return exeCMD(vssPath, localPath, "get");352 }353 354 #region 弃用355 //public static bool checkOut(string vssPath, string localPath, string selectFileName)356 //{357 // try358 // {359 // VSSItem vssitem = db.get_VSSItem(vssPath, false);360 // IVSSItems ivssitems = vssitem.get_Items(false);361 // localPath = localPath.EndsWith(@"\") ? localPath : localPath + @"\";362 // foreach (IVSSItem ivssitem in ivssitems)363 // {364 // if (ivssitem.Name == selectFileName)365 // {366 // ivssitem.Checkout("checkout", localPath + ivssitem.Name, 0);367 // }368 // }369 // return true;370 // }371 // catch (Exception ex)372 // {373 // System.Diagnostics.Debug.WriteLine(ex.Message);374 // return false;375 // }376 //} 377 #endregion378 379 }380 }
每个函数就不讲了,主要是分清vsspath和localpath的区别。
简单登陆
1 private void btnBrowse_Click(object sender, EventArgs e) 2 { 3 OpenFileDialog ofd = new OpenFileDialog() 4 { 5 Filter = "VSS配置文件|*.ini", 6 Title = "打开VSS数据库文件" 7 }; 8 if (ofd.ShowDialog() == DialogResult.OK) 9 {10 tboxVSS.Text = ofd.FileName;11 }12 13 }14 15 private void btnLogin_Click(object sender, EventArgs e)16 {17 string[] messboxText ={18 "VSS打开错误!\r\n请检查配置重试。",19 "VSS配置文件不存在!"20 };21 22 if (tboxVSS.Text == "")23 {24 return;25 }26 if (System.IO.File.Exists(tboxVSS.Text))27 {28 //打开VSS29 if (VSSHelper.openVSS(tboxVSS.Text, tboxUserName.Text, tboxPassword.Text))30 {31 this.Close();32 }33 else34 {35 //if (MessageBox.Show(messboxText[0], "错误", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) != DialogResult.Retry)36 //{37 // this.Close();38 //}39 MessageBox.Show(messboxText[0], "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);40 }41 }42 else43 {44 MessageBox.Show(messboxText[1], "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);45 46 }47 }
checkIn,checkOut 使用:
1 //提交到VSS 2 void menuItemSubmit2Vss_Click(object sender, System.EventArgs e) 3 { 4 if (VSSHelper.checkVSSOpen()) 5 { 6 if (VSSHelper.creatSub(treeVwExplorer.SelectedNode.FullPath, "$/")) 7 { 8 MessageBox.Show("提交成功!", "提示"); 9 }10 }11 else12 {13 MessageBox.Show("您尚未登录VSS\r\n请登录后重试", "错误");14 FrmVSSLogin frm = new FrmVSSLogin();15 frm.ShowDialog();16 }17 18 }19 //Get右键菜单处理事件20 void menuItemGet_Click(object sender, System.EventArgs e)21 {22 string vssPath, localPath;23 if (matchPath(treeVwExplorer.SelectedNode, out vssPath, out localPath))24 {25 bool result = VSSHelper.get(vssPath, localPath);26 }27 }28 //CheckOut右键菜单处理事件29 void menuItemCheckOut_Click(object sender, System.EventArgs e)30 {31 32 string vssPath, localPath;33 if (matchPath(treeVwExplorer.SelectedNode, out vssPath, out localPath))34 {35 //bool result = VSSHelper.checkOut(vssPath, localPath);36 if (VSSHelper.checkOut(vssPath, localPath))37 {38 //setTreeNodeColor(treeVwExplorer.SelectedNode, Color.LightBlue);39 setTreeNodeImg(treeVwExplorer.SelectedNode, true);40 }41 }42 43 44 45 }46 //CheckIn右键菜单处理事件47 void menuItemCheckIn_Click(object sender, System.EventArgs e)48 {49 50 string vssPath, localPath;51 if (matchPath(treeVwExplorer.SelectedNode, out vssPath, out localPath))52 {53 //bool result = VSSHelper.checkIn(vssPath, localPath);54 if (VSSHelper.checkIn(vssPath, localPath))55 {56 //setTreeNodeColor(treeVwExplorer.SelectedNode, Color.Transparent);57 setTreeNodeImg(treeVwExplorer.SelectedNode, false);58 }59 }60 61 62 }
因为是整理东西翻出来的项目中一小块代码,就不提供打包下载服务了。O(∩_∩)O哈哈~
有需求的直接使用VSSHelper.cs就好。保证可用。
打完收工。
.net中操作Visual SourceSafe