熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

用C#去除代碼的SourceSafe管理(1)

2013-11-13 10:17:35  來源: .NET編程 

  經常看一些的程序有些一個解決方案帶有多個項目由於代碼比較多多人開發所以好多下的工程是用source safe進行版本控制的而用source safe進行版本控制需要局域網路徑共享因此好多項目換一台機器打開會出現一些問題比如解決方案看起來是受源代碼管理但無法找到它的綁定信息……之類的提示信息很多有時候修改了代碼還保存不了所以想把他去掉下面是對項目管理前後的一些對比

  一工程項目比較

  同沒有受Source Safe代碼管理的工程相比

  .   多出了sccvssscc和vspscc文件

  .   C#項目文件(csproj)裡面添加了幾行標簽

  SccProjectName = SAK

  SccLocalPath = SAK

  SccAuxPath = SAK

  SccProvider = SAK

  .在解決方案文件(sln)中中增加了如下節點原素

  GlobalSection(SourceCodeControl) = preSolution

  SccNumberOfProjects =

  SccLocalPath =

  ……

  SccLocalPath = SUBSCRIBE_TOOLS

  CanCheckoutShared = false

  EndGlobalSection

  二編寫實現的類

  既然文件增多了還有有些文件被修改所以想通過編程把他修改回原樣這樣可能可以去掉那些提示信息所以就寫了下面的代碼

  功能去除的原代碼Source safe 管理

  using System;

  using SystemIO;

  using SystemText;

  using SystemThreading;

  namespace ZZ

  {

  /// <summary>

  /// 操作信息事件代理

  /// </summary>

  public delegate void OperateNotifyHandler(object senderVssEventArgs 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)

  {

  thisoperatePath = operatePath;

  }

  OperatePath屬性用來設置或獲取當前需要處理的工程路徑不過在運行時最好不要設置他

  /// <summary>

  /// 設置解決方案工程路徑

  /// </summary>

  public string OperatePath

  {

  get{return thisoperatePath;}

  set{thisoperatePath = value;}

  }

  下面是一個public 修飾符的函數也是類實例的惟一對外公開的方法裡面用了兩個線程來分別刪除文件和修改文件

  /// <summary>

  /// 去除Source Safe代碼管理

  /// </summary>

  public void RemoveVss()

  {

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

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

  deleteThreadStart();

  RemoveVssIdentifyThreadStart();

  }

  後來測試了一下deleteThread的完成要比RemoveVssIdentifyThread快一些當然也可以再開一個線程來分擔文件的修改不過這裡需要注意的是好多文件是帶只讀屬性的所以還要把文件屬性設置成Normal才能順利完成操作否則會拋出異常

  這裡使用了遞歸來刪除相關文件由三個函數構成

  /// <summary>

  /// 線程委托函數完成刪除*scc*vssscc以及*vspscc文件功能

  /// </summary>

  private void DeleteVssFile()

  {

  DeleteVssFile(thisoperatePath);

  //通知刪除文件結束

  OnThreadCompleted(thisnew EventArgs());

  }

  /// <summary>

  ///  遞歸函數刪除*scc*vssscc以及*vspscc文件

  /// </summary>

  /// <param name=path>當前處理路徑</param>

  private void DeleteVssFile(string path)

  {

  DeleteFile(DirectoryGetFiles(path*scc));

  DeleteFile(DirectoryGetFiles(path*vssscc));

  DeleteFile(DirectoryGetFiles(path*vspscc));

  foreach(string dir in DirectoryGetDirectories(path))

  DeleteVssFile(dir);

  }

  /// <summary>

  /// 刪除文件真正刪除文件

  /// </summary>

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

  private void DeleteFile(string [] files)

  {

  foreach(string file in files)

  {

  FileInfo fi = new FileInfo(file);

  fiAttributes = FileAttributesNormal;

  FileDelete(file);

  OnOperateNotify(thisnew VssEventArgs(file+刪除完成));

  }

  }

  對於sln解決方案文件和csprojC#項目文件的修改也采用了遞歸實現

  /// <summary>

  /// 線程委托函數去除*sln解決方案文件和*csprojC#項目文件的Vss關聯標簽

  /// </summary>

  private void RemoveVssIdentify()

  {

  RemoveVssTag(thisoperatePath);

  //通知去除標簽結束

  OnThreadCompleted(thisnew EventArgs());

  }

  /// <summary>

  /// 去除*sln解決方案文件和*csprojC#項目文件的Vss關聯標簽

  /// </summary>

  /// <param name=path>當前處理路徑</param>

  private void RemoveVssTag(string path)

  {

  RemoveTagContent(DirectoryGetFiles(path*sln));

  RemoveTagContent(DirectoryGetFiles(path*csproj));

  foreach(string dir in DirectoryGetDirectories(path))

  RemoveVssTag(dir);

  }

  下面的函數用來分析處理文件的修改因為都是做刪除部分文件內容的工作所以把處理函數寫成了一個

  /// <summary>

  /// 去除*sln解決方案文件和*csprojC#項目文件的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);

  fiAttributes =FileAttributesNormal;

  if(fiExtension == sln)//如果是解決方案文件

  {

  strStart = GlobalSection(SourceCodeControl);

  strEnd = EndGlobalSection;

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

  }

  else//如果是項目文件

  {

  strStart = SccProjectName;

  strEnd = >;

  offSet = ;

  }

  try

  {

  int start;//Vss標簽文本開始索引

  int end;//Vss標簽文本結束索引

  string content;//文件內容

  using(FileStream fs = new FileStream(fileFileModeOpenFileAccessReadWriteFileShareReadWrite))

  {

  StreamReader sr = new StreamReader(fs);

  content = srReadToEnd();

  srClose();

  start = contentIndexOf(strStart);

  }

  if(start!=)//文件需要去除標簽

  {

  using(FileStream fs = new FileStream(fileFileModeTruncateFileAccessWriteFileShareRead))

  {

  end = start+contentSubstring(start)IndexOf(strEnd)+offSet;

  content = contentSubstring(start)+contentSubstring(end);

  StreamWriter sw = new StreamWriter(fs);

  swWrite(content);

  swClose();

  }

  OnOperateNotify(thisnew VssEventArgs(file+去除標簽完成));

  }

  }

  catch(Exception ex)

  {

  OnOperateNotify(thisnew VssEventArgs(file+操作錯誤+exToString()));

  }

  }

  }

  當此為止上面的程序實現了主要的功能不過上面定義的事件下面就是關於事件的函數

  /// <summary>

  /// 操作信息事件通知

  /// </summary>

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

  /// <param name=e>參數</param>

  protected virtual void OnOperateNotify(object senderVssEventArgs e)

  {

  if(OperateNotify!=null)

  OperateNotify(sendere);

  }

  /// <summary>

  /// 線程結束事件通知

  /// </summary>

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

  /// <param name=e>參數</param>

  protected virtual void OnThreadCompleted(object senderEventArgs e)

  {

  if(ThreadCompleted!=null)

  ThreadCompleted(sendere);

  }

  }

  相對於事件中的參數這裡定義了一個類從EventArgs繼承裡面只包含一個字段用來保存信息

  /// <summary>

  /// 消息通知事件參數類

  /// </summary>

  public class VssEventArgs : EventArgs

  {

  private string message;

  /// <summary>

  /// 構造函數

  /// </summary>

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

  public VssEventArgs(string message)

  {

  ssage = message;

  }

  /// <summary>

  /// 消息內容

  /// </summary>

  public string Message

  {

  get{return ssage;}

  }

  }

  }//命名空間


From:http://tw.wingwit.com/Article/program/net/201311/13178.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.