Click here to Skip to main content
Email Password   helpLost your password?

Sample Image - RemoveSCCInfo.jpg

Introduction

With the yet to be released SourceSafe 2005, we decided to switch back to a SourceSafe database for some of our projects instead of a CVS repository. And saying that it have been quite a pain is not even beginning to come close to reality. Source-Code integration in VS.NET is not a nightmare, but you have to change your project files and delete a few other files to get rid of it. Failing to do so may get you in real trouble when rebinding to another SCC provider.

This "article" (OK, it may not be a great one, but that's my first one for Code Project) summarizes what I have found while building this tool, either by myself or on blogs and newsgroups.

Using the code

I decided to write this small tool to help getting rid of everything that is related to source-code control. It's quite straightforward to use: just enter the path to your project or solution file and click Continue, and it should work.

For now, there are (quite) a few limitations:

Points of Interest

Visual Studio keeps its SCC information in quite a few places. And if you want to get clean, you'll have to get rid of all of them.

The Solution File (.sln)

The solution file contains a section that is dedicated to SCC. If you open the .sln file in a text editor, you'll have something that looks like :

Microsoft Visual Studio Solution File, Format Version 8.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyProject", 
    "Projects\MyProject.csproj", "{B1A1C06F-EB84-4215-975E-6B0B57496BAC}" 
        ProjectSection(ProjectDependencies) = postProject 
        EndProjectSection
EndProject 
        ... other projects in your solution ...
Global
    GlobalSection(SourceCodeControl) = preSolution
        SccNumberOfProjects = 1
        SccProjectName0 = Perforce\u0020Project
        SccLocalPath0 = .
        SccProvider0 = MSSCCI:Perforce\u0020SCM
        CanCheckoutShared = true
        SolutionUniqueID = {0F9ACC79-634F-44DB-9C57-C4B0C461AA7B}
        SccProjectUniqueName1 = Projects\\MyProject.csproj
        SccLocalPath1 = MyProject
    EndGlobalSection
        ... other global sections ...        
EndGlobal

Just delete the GlobalSection(SourceCodeControl) ... EndGlobalSection and save the file.

The Solution User Options File (.suo)

I didn't find any real good solution besides deleting the file. But don't worry, VS.NET will create it back when you open the sln file.

The projects file (C# .csproj and VB.NET .vbproj)

Those files are XML based, so it won't really be hard to clean them. All you have to do is remove the following attributes on the main project node (which is named CSharp or VisualBasic):

The setup projects files (.vdproj)

They are quite similar to the .csproj and .vbproj except on one point: they are not XML based. You'll have to remove the following lines :

"SccProjectName" = "XXXXXXXXXXXXXXXXXX"
"SccLocalPath" = "8:..\\.."
"SccAuxPath" = "8:"
"SccProvider" = "XXXXXXXXXXXXXXXXXX"
All the other stuff

Visual Studio creates a few files for managing the source code integration, so you'll have to delete those files:

If you use MS SourceSafe as your source "database", you'll also find a vssver.scc file in each folder: delete them all if you want, but I didn't have any issues for not having done so.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralDoes this work with VS2005?
Keith Mallen
10:19 21 Apr '08  
It sounds like just what I need, but we are VS2005.

Thanks,
Keith
GeneralUse UnBind instead!
alinconstantin
8:44 21 Jul '07  
Before using such tool, someone should try the File/SourceControl/ChangeSourceControl dialog and Unbind-ing all the bound projects... That is the recommended way to disable source control integration for projects.

Other tips:
- do not delete suo files if you want to work with web projects. If you do, you risk either opening another user's website or even not opening the project at all.
- no need to delete vssver.scc, mssccprj.scc files - they are created by VSS, not by scc integration.

Alin
GeneralCool and fast
Vastug
3:24 7 Aug '06  
Hi, thanks for the good solution. I'm download a project from this code project site last night and have directly problem with scc-files and do not what i'm do now to solve the problem. I'm search today and find your solution, download, run and the problem was gone.
Nice Smile

thanks,
Peter
GeneralIs this the same as Unbind?
Giles
23:38 8 May '06  
Bring up the Source Control toolbar.

Click "Change Source Control".
On each bound project, select it, and then click the unbind button.

G
GeneralThanks
j0ey
5:35 2 May '06  
This tool has been out awhile and I come back about once every 3 months to use it. It has worked flawlessly on large (30+ projects in a solution) and small solutions.Big Grin
GeneralHas anyone had this working with VS2005.NET Projects?
Peter Connors
7:31 27 Apr '06  
It's throwing a file not found error in GetProjectsFromSlnFile...I'm still playing with it, but if I could know if this should be working OOTB it would be nice...

Confused



Thanks,

Peter
GeneralSource Code
anger666
3:08 23 Feb '06  
Hi,

thank you for this great tool, because i have to do a very similar task (change form binary references to project references) i am interested in your source code. Is it open source? Can i get it?

thanks Wolfi
GeneralRe: Source Code
mcarbenay
3:36 23 Feb '06  
Hello,

Source code is included in the zip file. You may use it as you want, provided you add a (c) Creo Ignem & Michael CARBENAY if you don't change anything. If you release something which is "based" (that is : you write your code using part of my code), nothing as to be said about my work.

By the way, i'll appreciate if you publish your tool on codeproject or send me a version...

Michael CARBENAY
Creo Ignem
GeneralRe: Source Code
anger666
3:44 23 Feb '06  
Thanks for the very fast answer...
Wolfi
GeneralThanks: Question on VSS & the IDE
Len Miller
4:30 1 Feb '06  
Hi,

Thanks for the tool & the great information.

Do you have any idea where the IDE or VSS stores it's information when you version control your stored procedures? (this is done via the Server Explorer window)

As an FYI - If you care - Here is an old sample of how to do this
http://weblogs.asp.net/fmarguerie/archive/2003/02/24/2880.aspx

I am versioning my procedures in VSS through the Server Explorer window, and my VSS database has moved. Everything is now hosed, and I cannot find where to tell the IDE, VSS, or whatever where the new VSS database is located. The Server Explorer window is independent of any solution.

Thanks,
-Len


Thanks,
-Len Miller

"If I had eight hours to chop down a tree, I'd spend six sharpening my axe."
-Abraham Lincoln
GeneralC++ projects?
Anna-Jayne Metcalfe
5:01 10 Jan '06  
Any likelyhood of you adding support for C++ projects (*.vcproj) in the near future?

Anna Rose

Currently working mostly on: Visual Lint Cool

Anna's Place | Tears and Laughter
"Be yourself - not what others think you should be"
- Marcia Graesch

"Anna's just a sexy-looking lesbian tart"
- A friend, trying to wind me up. It didn't work.

GeneralRe: C++ projects?
mcarbenay
5:52 10 Jan '06  
Err... C++ projects... right... err...

I didn't look at the visual c++ project file format, still using visual c++ 6.0 for my own.

I'll try to look into it and see if I can add support in the next few days.

Michael CARBENAY
Creo Ignem
GeneralRe: C++ projects?
Anna-Jayne Metcalfe
9:47 10 Jan '06  
Thanks. Smile

The format is pretty similar to C# and V.NET, so you should find it familiar.

Anna Rose

Currently working mostly on: Visual Lint Cool

Anna's Place | Tears and Laughter
"Be yourself - not what others think you should be"
- Marcia Graesch

"Anna's just a sexy-looking lesbian tart"
- A friend, trying to wind me up. It didn't work.

GeneralThanks!
-Dy
0:37 21 Sep '05  
Thanks very much, this has saved me a lot of time and effort


-Dy
GeneralThanks a lot
Gaben
11:37 29 Jun '05  
This is a time saver!;) I appreciate your contribution.

Gabe
GeneralHelp Translating the regular expression for use in VB.net
Chubby Arse
23:16 12 May '05  
Hi,

I've used the source safe utilities in my own addin, which backs up a solution to a zip file, and part of the process is to remove sourcesafe information.

I'm struggling, becuase my VB.net translation works up until the point where the regular expressions examine the file text, and I suspect it's where I translated the C# RegEX to vb.net.....

Would someone help me with this?

From Method PatchDeployProject:

C# Code:
Regex r = new Regex("\\\"Scc\\w*\\\"\\s*=\\s*\\\".*\\\""); VB.Net Code:
Dim objRegEx As New Regex("\\""Scc\w*\\""\s*=\s*\\"".*\\""")
From Method PatchXMLProjectFile:

C# Code:
Regex r = new Regex("Scc\\w*\\s*=\\s*\\\".*\\\""); VB.Net Code:
Dim objRegEx As New Regex("Scc\w*\s*=\s*\\"".*\\""")

Thanks - Great bit of code Michael.......

GeneralRe: Help Translating the regular expression for use in VB.net
mcarbenay
0:43 13 May '05  
err...

I'm not really good in VB.net and don't have this project on my office computer for testing. but if i'm not mistaken you should replace \\ by \ and \" by ""

so the lines Dim objRegEx As New Regex("Scc\w*\s*=\s*\"".*\""") may work for PatchXMLProjectFile and Dim objRegEx As New Regex("\""Scc\w*\""\s*=\s*\"".*\""") for PatchDeployProject should do the trick.

Let me know if it does the trick or not.




Michael CARBENAY
Creo Ignem
GeneralRe: Help Translating the regular expression for use in VB.net
Chubby Arse
6:18 16 May '05  
That did it.

Cheers Michael.
GeneralRe: Help Translating the regular expression for use in VB.net
mcarbenay
11:05 16 May '05  
OK, so I'm now officialy a vb.net guru Wink

I hope you'll post your add-in here, I'm always happy to test such an improvement to the (rather) poor vstudio.

Michael CARBENAY
Creo Ignem
GeneralVery cool
msureshkr
9:46 14 Feb '05  
This was the project I was looking for at present.
Very nice work....

GeneralCool
rico65
0:59 20 Dec '04  
Exactly was I needed at the moment, it just worked for the project I received from a friend!
GeneralBackup leave directory when "don't backup" is torn on
Mike Chaliy
21:33 7 Oct '04  
internal abstract class RemoveSccBaseCommand
{
[Skipped]

public void Do()
{
[Skipped]
if (!_createBackup)
{
Directory.Delete(_backupDir);
}
}

Thank you. I like this tool.
GeneralRe: Backup leave directory when "don't backup" is torn on
mcarbenay
22:54 7 Oct '04  
Errr.... what could I say ? "I've never tested with the 'don't backup' flag on ?" yes that could be what I've had to say....

Thanx.

Michael CARBENAY
GeneralRe: Backup leave directory when "don't backup" is torn on
Greg Norris
12:39 24 Nov '05  
I prefer the - don't create it if you don't need it theory.
That way there is no argument about accidently deleting a desired backup after the event. The script above would delete a previous backup even if it was desired.. I used..

if (_createBackup)
if(!Directory.Exists(_backupDir))
Directory.CreateDirectory(_backupDir);

Excellent tool. Thank you Michael.

Greg
GeneralI don't know...
mracka
20:49 22 Jul '04  
I wrote this. Just copy text to a *.js file. Put the file to the same dir, where *.sln is. No need for exe...

<code>
/// Global ------------------------------------------------------

var deleteByForce = true;
var consoleOnly = true;
var defaultTimeOut = 1;
var showDetails = false;

var WSShell;
var fso;
var currentFolder;
var deletedFiles = 0;
var modifiedFiles = 0;
var ForReading = 1, ForWriting = 2, ForAppending = 8;
var CharSetDefault = -2, CharSetUnicode = -1, CharSetAscii = 0;
var AttrNormal = 0, AttrReadOnly = 1, AttrHidden = 2, AttrSystem = 4,
AttrVolume = 8, AttrDirectory = 16, AttrArchive = 32, AttrAlias = 1024,
AttrCompressed = 2048;


Init();
Main();
//Test();


/// Main ------------------------------------------------------

function Main() {
    
     var text;
         
     // say hello
     text =      "Remove from SourceSafe has started.";
     Out(text,true);
     COut("Working folder: \r\n"+ currentFolder);
    
    
     // delete files
     // *.suo, *.eto, *.vssscc, *.vspscc, vssver.scc, mssccprj.scc
     DeleteFiles("[.]*([.]suo$|[.]eto$|[.]vssscc$|[.]vspscc$|vssver[.]scc$|mssccprj[.]scc$)");
    
     // modify files
     // *.etp, *.sln, *.csproj
     ModifyFiles("[.]*([.]etp$|[.]sln$|[.]csproj$)");
    
     // say goodbye
     text =      "Remove from SourceSafe has finished. \r\n\r\n"
               + "Deleted files:   \t" + deletedFiles + "\r\n"
               + "Modified files:   \t" + modifiedFiles + "\r\n";
     Out(text,false);
}

function Init() {
    
     // detect command line
     try {
          WScript.StdOut.WriteLine(" ");
     } catch (e) {
          consoleOnly = false;
     }
    
     // initialize
     WSShell = new ActiveXObject("WScript.Shell");
     fso = new ActiveXObject("Scripting.FileSystemObject");
     currentFolder = GetCurrentFolder();
}

/// Files ------------------------------------------------------

// getcurrent folder
function GetCurrentFolder() {
    
     return fso.GetFolder(fso.GetFile(WScript.ScriptFullName).ParentFolder);
}


// delete files by mask
function DeleteFiles(mask) {
     var files = FindFiles(mask);
     var i;
    
     Out("Deleting files", true);
    
     for (i=0; i<files.length; i++) {
          try {
               fso.DeleteFile(files[i], deleteByForce);
               deletedFiles ++;
          } catch (e) {
               WScript.echo(e.Message);
          }
     }
    
     if (deletedFiles == 0) {
          COut("No files were deleted.");
     }
}


// find files
function FindFiles(mask) {
     return GetFiles(currentFolder, mask);
}

// determine, if filename matches given mask
function MatchesMask(file, mask) {
     return new RegExp(mask).test(file);
}

// get files in current folder & subfolders
function GetFiles(folder, mask) {
     var result = new Array();
     // do files in current folder
     var files = new Enumerator(folder.Files);
     for (; !files.atEnd(); files.moveNext()) {
          if (MatchesMask(files.item(), mask)) {
               result.push("" + files.item());
          }
     }
     // do subfolders in current folder
     var folders = new Enumerator(folder.SubFolders);
     for (; !folders.atEnd(); folders.moveNext()) {
          result = result.concat(GetFiles(folders.item(), mask));
     }
     return result;
}

/// Output ------------------------------------------------------

// output
function Out(text, useTimeOut) {
     if (useTimeOut) {
          useTimeOut = defaultTimeOut;
     } else {
          useTimeOut = -1;
     }

     if (consoleOnly) {
          WScript.StdOut.WriteLine(text);
     } else {
          WSShell.Popup(text, useTimeOut, "Remove from SourceSafe");
     }
}

// output
function COut(text, useTimeOut) {
     if (useTimeOut) {
          useTimeOut = defaultTimeOut;
     } else {
          useTimeOut = -1;
     }

     if (consoleOnly) {
          WScript.StdOut.WriteLine(text);
     }
}


/// Modify ------------------------------------------------------

// modify all files matching given mask
function ModifyFiles(mask) {
    
     var files = FindFiles(mask);
     var i;
    
     Out("Modifying files", true);
    
     for (i=0; i<files.length; i++) {
//               WScript.echo(files[i]);
//          try {
               ModifyFile(fso.GetFile(files[i]));
               modifiedFiles ++;
//          } catch (e) {
//               WScript.echo(e.description);
//          }
     }

     if (modifiedFiles == 0) {
          COut("No files were modified.");
     }
}


function ModifyFile(file) {

     switch (fso.GetExtensionName(file.Path).toLowerCase()) {
          case "etp":
               ModifyFileETP(file);
               break;
          case "sln":
               ModifyFileSLN(file);
               break;
          case "csproj":
               ModifyFileCSPROJ(file);
               break;
     }
}

function ReadFile(file) {
     var stream = file.OpenAsTextStream(ForReading, CharSetDefault);
     text = stream.ReadAll();
     stream.Close();
     return text;
}

function WriteFile(file, text) {
     var ro = ((file.Attributes & AttrReadOnly) != 0);
     if (ro) file.Attributes -= AttrReadOnly;
     var stream = file.OpenAsTextStream(ForWriting, CharSetDefault);
     stream.Write(text);
     stream.Close();
     if (ro) file.Attributes += AttrReadOnly;
}


// remove element <SourceControlSettings>...</SourceControlSettings>
function ModifyFileETP(file) {

     var text;
     var re1 = new RegExp('(\\s*<SourceControlSettings(\\s[^>]*)?>[.\\s\\S\\r\\n]*<\\/SourceControlSettings>)','m');
    
     text = ReadFile(file);
     text = text.replace(re1, "");
     WriteFile(file, text);

}

// remove section GlobalSection(SourceCodeControl) = preSolution ... EndGlobalSection
function ModifyFileSLN(file) {
    
     var text;
     var re1 = new RegExp('(\\s*GlobalSection\\(SourceCodeControl\\))[.\\r\\n\\s\\S]*?EndGlobalSection','m');

     text = ReadFile(file);
     text = text.replace(re1, "");
     WriteFile(file, text);
    
}

// remove lines with SccProjectName, SccLocalPath, SccAuxPath, SccProvider
function ModifyFileCSPROJ(file) {

     var text;
     var re1 = new RegExp('(^\\s*SccProjectName = .*$)', 'm');
     var re2 = new RegExp('(^\\s*SccLocalPath = .*$)', 'm');
     var re3 = new RegExp('(^\\s*SccAuxPath = .*$)', 'm');
     var re4 = new RegExp('(^\\s*SccProvider = .*$)', 'm');

     text = ReadFile(file);
     text = text.replace(re1, "");
     text = text.replace(re2, "");
     text = text.replace(re3, "");
     text = text.replace(re4, "");
     WriteFile(file, text);
    
}

</code>


Last Updated 16 Jul 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010