首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
psyl (153)
capsicum29 (8)
qdzx2008 (51)
ShowLong (1)
cyp403 (16)
yjz0065 (114)
lphpc (31)
smallnest (63)
tellmenow (22)
cutemouse (22)
CSDN - 文档中心 - .NET 阅读:5286   评论: 2    参与评论
标题   用C#去除代码的SourceSafe管理     选择自 zhzuo 的 Blog
关键字   C# SourceSafe
出处  

C#去除代码的SourceSafe管理

作者:秋枫

         经常看一些的程序,有些一个解决方案带有多个项目,由于代码比较多,多人开发,所以好多vs.net下的工程是用source safe进行版本控制的。而用source safe进行版本控制需要局域网路径共享,因此好多项目换一台机器打开会出现一些问题,比如“解决方案看起来是受源代码管理,但无法找到它的绑定信息……”之类的提示信息很多。有时候修改了代码还保存不了,所以想把他去掉,下面是对项目管理前后的一些对比。

 

 一、工程项目比较

同没有受Source Safe代码管理的工程相比:

1.   多出了.scc、.vssscc和.vspscc文件;

2.   C#项目文件(.csproj)里面添加了几行标签:

SccProjectName = "SAK"

SccLocalPath = "SAK"

SccAuxPath = "SAK"

SccProvider = "SAK"

3.在解决方案文件(.sln)中,中增加了如下节点原素:

         GlobalSection(SourceCodeControl) = preSolution

                   SccNumberOfProjects = 4

                   SccLocalPath0 = .

                   ……

SccLocalPath3 = SUBSCRIBE_TOOLS

                   CanCheckoutShared = false

         EndGlobalSection

 

二、编写实现的类

既然文件增多了,还有有些文件被修改,所以想通过编程把他修改回原样,这样可能可以去掉那些提示信息,所以就写了下面的代码。

//**********************************************************

// 程序:郑佐  zhzuocn@163.com  2004/06/10 

// 功能:去除C#.net的原代码Source safe 管理

//**********************************************************

using System;

using System.IO;

using System.Text;

using System.Threading;

namespace ZZ

{

     /// <summary>

     /// 操作信息事件代理

     /// </summary>

     public delegate void OperateNotifyHandler(object sender,VssEventArgs e);

     /// <summary>

     /// VssConverter 处理解决方案或项目的SourceSafe关联。

     /// </summary>

     public class VssConverter

     {

         //操作根目录

         private string operatePath;

         /// <summary>

         /// 操作信息事件

         /// </summary>

         public event OperateNotifyHandler OperateNotify;

         /// <summary>

         /// 线程结束通知事件

         /// </summary>

         public event EventHandler ThreadCompleted;

         /// <summary>

         /// 构造函数

         /// </summary>

         /// <param name="operatePath">项目路径</param>

         public VssConverter(string operatePath)

         {

              this.operatePath = operatePath;

         }

     OperatePath属性,用来设置或获取当前需要处理的工程路径,不过在运行时最好不要设置他,

         /// <summary>

         /// 设置解决方案工程路径

         /// </summary>

         public string OperatePath

         {

              get{return this.operatePath;}

              set{this.operatePath = value;}

         }

     下面是一个public 修饰符的函数,也是类实例的惟一对外公开的方法,里面用了两个线程来分别删除文件和修改文件。

         /// <summary>

         /// 去除Source Safe代码管理

         /// </summary>

         public void RemoveVss()

         {

              Thread deleteThread = new Thread(new ThreadStart(DeleteVssFile));

              Thread RemoveVssIdentifyThread = new Thread(new ThreadStart(RemoveVssIdentify));

              deleteThread.Start();

              RemoveVssIdentifyThread.Start();

         }

后来测试了一下deleteThread的完成要比RemoveVssIdentifyThread快一些,当然也可以再开一个线程来分担文件的修改,不过这里需要注意的是好多文件是带只读属性的,所以还要把文件属性设置成Normal才能顺利完成操作,否则会抛出异常。

这里使用了递归来删除相关文件,由三个函数构成:

         /// <summary>

         /// 线程委托函数,完成删除"*.scc","*.vssscc"以及*.vspscc文件功能。

         /// </summary>

         private void DeleteVssFile()

         {

              DeleteVssFile(this.operatePath);

              //通知删除文件结束

              OnThreadCompleted(this,new EventArgs());

         }

         /// <summary>

         ///  递归函数,删除"*.scc","*.vssscc"以及*.vspscc文件。

         /// </summary>

         /// <param name="path">当前处理路径</param>

         private void DeleteVssFile(string path)

         {

              DeleteFile(Directory.GetFiles(path,"*.scc"));

              DeleteFile(Directory.GetFiles(path,"*.vssscc"));

              DeleteFile(Directory.GetFiles(path,"*.vspscc"));

              foreach(string dir in Directory.GetDirectories(path))

                   DeleteVssFile(dir);

         }

         /// <summary>

         /// 删除文件,真正删除文件

         /// </summary>

         /// <param name="files"></param>

         private void DeleteFile(string [] files)

         {

              foreach(string file in files)

              {

                   FileInfo fi = new FileInfo(file);

                   fi.Attributes = FileAttributes.Normal;

                   File.Delete(file);

                   OnOperateNotify(this,new VssEventArgs(file+"删除完成"));

              }

         }

对于".sln"解决方案文件和".csproj’"C#项目文件的修改也采用了递归实现:

                   /// <summary>

         /// 线程委托函数,去除"*.sln"解决方案文件和"*.csproj"C#项目文件的.Vss关联标签。

         /// </summary>

         private void RemoveVssIdentify()

         {

              RemoveVssTag(this.operatePath);

              //通知去除标签结束

              OnThreadCompleted(this,new EventArgs());

         }

        

         /// <summary>

         /// 去除"*.sln"解决方案文件和"*.csproj"C#项目文件的.Vss关联标签。

         /// </summary>

         /// <param name="path">当前处理路径</param>

         private void RemoveVssTag(string path)

         {

              RemoveTagContent(Directory.GetFiles(path,"*.sln"));

              RemoveTagContent(Directory.GetFiles(path,"*.csproj"));

              foreach(string dir in Directory.GetDirectories(path))

                   RemoveVssTag(dir);

         }

     下面的函数用来分析处理文件的修改,因为都是做删除部分文件内容的工作,所以把处理函数写成了一个,

         /// <summary>

         /// 去除"*.sln"解决方案文件和"*.csproj"C#项目文件的.Vss关联标签。

         /// </summary>

         /// <param name="file">当前处理文件</param>

         private void RemoveTagContent(string [] files)

         {

              foreach(string file in files)

              {

                   string strStart; //Vss标签文本开始内容

                   string strEnd; //标签文本结束内容

                   int offSet;//结束标签文本的偏移量

                   FileInfo fi = new FileInfo(file);

                   fi.Attributes =FileAttributes.Normal;

                   if(fi.Extension == ".sln")//如果是解决方案文件

                   {

                       strStart = "GlobalSection(SourceCodeControl)";

                       strEnd = "EndGlobalSection";

                       offSet = 19;//包含\r\n和空格

                   }

                   else//如果是项目文件

                   {

                       strStart = "SccProjectName";

                       strEnd = ">";

                       offSet = 0;

                   }

                   try

                   {

                       int start;//Vss标签文本开始索引

                       int end;//Vss标签文本结束索引

                       string content;//文件内容

                       using(FileStream fs = new FileStream(file,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite))

                       {

                            StreamReader sr = new StreamReader(fs);

                            content = sr.ReadToEnd();

                            sr.Close();

                            start = content.IndexOf(strStart);

                       }

                       if(start!=-1)//文件需要去除标签

                       {

                            using(FileStream fs = new FileStream(file,FileMode.Truncate,FileAccess.Write,FileShare.Read))

                            {

                                 end = start+content.Substring(start).IndexOf(strEnd)+offSet;

                                 content = content.Substring(0,start)+content.Substring(end);

                                 StreamWriter sw = new StreamWriter(fs);

                                 sw.Write(content);

                                 sw.Close();

                            }

                            OnOperateNotify(this,new VssEventArgs(file+"去除标签完成"));

                       }

                   }

                   catch(Exception ex)

                   {

                       OnOperateNotify(this,new VssEventArgs(file+"操作错误:"+ex.ToString()));

                   }

              }            

     }

当此为止,上面的程序实现了主要的功能,不过上面定义的事件,下面就是关于事件的函数,

         /// <summary>

         /// 操作信息事件通知

         /// </summary>

         /// <param name="sender">VssConverter</param>

         /// <param name="e">参数,</param>

         protected virtual void OnOperateNotify(object sender,VssEventArgs e)

         {

              if(OperateNotify!=null)

                   OperateNotify(sender,e);

         }

         /// <summary>

         /// 线程结束事件通知

         /// </summary>

         /// <param name="sender">VssConverter</param>

         /// <param name="e">参数</param>

         protected virtual void OnThreadCompleted(object sender,EventArgs e)

         {

              if(ThreadCompleted!=null)

                   ThreadCompleted(sender,e);

     }

}

相对于事件中的参数,这里定义了一个类从EventArgs继承,里面只包含一个字段用来保存信息,

/// <summary>

     /// 消息通知事件参数类

     /// </summary>

     public class VssEventArgs : EventArgs

     {

         private string message;

         /// <summary>

         /// 构造函数

         /// </summary>

         /// <param name="message"></param>

         public VssEventArgs(string message)

         {

              this.message = message;

         }

         /// <summary>

         /// 消息内容

         /// </summary>

         public string Message

         {

              get{return this.message;}

         }

}

}//命名空间


 


相关文章
对该文的评论
CSDN 网友 ( 2004-07-06)
开放ASP.NET + C#开发客户服务系统源代码
演示地址:http://www.szlon.com
baryon ( 2004-06-16)
03/31/03 14:25 从VC7的项目里去除SourceSafe信息

http://www.geocities.jp/baryonlee/python/workshop/erasevss.htm