.net中操作Visual SourceSafe
想起以前写的时候,因为资料比较匮乏,只能边研究边测试,走了不少弯路。
由于一些个人的原因(有点健忘,有点懒),一直没分享出来。今天趁着有点空,刷刷blog。
ps:上一个绘制c语言头文件包含关系图的小工具(https://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 #endregion
104 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 try
116 {
117 if (fileInfo.Extension.ToLower() != ".scc")
118 {
119 //添加本地文件到VSS
120 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 try
134 {
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 else
152 {
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 //try
162 //{
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 // //包括子目录中的文件。并把所有文件checkout
173 // 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 // //项目文件,直接checkout
182 // 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 #endregion
203 }
204 private static bool exeCMD(string vssPath, string localPath, string cmd)
205 {
206 try
207 {
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 //try
302 //{
303 // VSSItem vssitem = db.get_VSSItem(vssPath, false);
304 // if (vssitem.Type == 1)
305 // {
306 // //IsCheckedOut==0 未checkout
307 // //若被checkout,则checkin
308 // 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 #endregion
348 }
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 // try
358 // {
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 #endregion
378
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 //打开VSS
29 if (VSSHelper.openVSS(tboxVSS.Text, tboxUserName.Text, tboxPassword.Text))
30 {
31 this.Close();
32 }
33 else
34 {
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 else
43 {
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 else
12 {
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 }
下一篇: 有谁管我叫爹