***Migrating Project and Solution Files from P4SCC to P4VS***
To successfully migrate a solution and its projects from the P4SCC plug-in to
the new P4VS plug-in, you must do the following:
1. Strip the bindings from the solution (sln) file and all of the project
files (csproj, vcxproj, etc.).
2. Ensure that MSSCCPROJ.SCC and other source-control-specific files are no
longer present.
3. Move all developers to P4VS. They must uninstall the old P4SCC plug-in.
There are two basic ways to remove the bindings from your project and solution
files.
The surest, safest, and Perforce recommended way to remove source control
bindings is to use Visual Studio to remove the bindings. To have Visual Studio
remove the bindings, first uninstall the P4SCC plug-in. Next, open your
solution in Visual Studio and, when prompted, choose the option to "Permanently
Remove Source Control Associated Bindings." When completed, the source control
bindings should have been removed from the project and solution files as well
as the Visual Studio source-control-specific files ending with *scc, including
MSSCCPRJ.SCC files.
On occasion, source control bindings and special files will not be removed by
Visual Studio because, for example, some projects were not loaded successfully
by the IDE. Try removing the projects that would not load from the solution and
"UnBind-ing" your solution one more time. If you still have no luck, please
contact Perforce Technical Support for further instructions.
After removing the P4SCC bindings, open Visual Studio. Assuming that P4VS has been
installed, make sure that it is selected as the source control provider:
1. Go to Tools -> Options.
2. Expand the "Source Control" section in the navigation tree.
3. Select the "Plug-in Selection" tab and choose "P4VS - Perforce
Plugin for Visual Studio" in the combo box.
Open a connection to Perforce using "File -> Open Connection to a Perforce Depot."
Open the modified solution using "File -> Open -> Project/Solution..." As long as
the solution is in the workspace specified by the connection, it will be bound to
the new P4VS plugin.
If you want to leave the P4SCC plug-in installed, you can use its "Change
Source Control" command. With a P4SCC-controlled solution loaded in Visual
Studio, you have the option to use the "UnBind" feature. "UnBind" is available
only if you are using the P4SCC plug-in. Look for the "UnBind" feature in
Visual Studio menu, File -> Source Control, "Change Source Control."
Alternatively, you can manually edit the solution project and solution files.
This may be required if Visual Studio was not able to remove the bindings using
the previous method. You will also need to delete the *.scc files, especially the
MSSCCPRJ.SCC files.
As P4SCC users know, solution files contain the following lines (although the
data varies based on you settings):
GlobalSection(SourceCodeControl) = preSolution
SccNumberOfProjects = 3
SccProjectName0 = Perforce\u0020Project
SccLocalPath0 = ..
SccProvider0 = MSSCCI:Perforce\u0020SCM
SccProjectFilePathRelativizedFromConnection0 = P4SCC_SAMPLE_PROJECT\\
SccProjectUniqueName1 = P4SCC_SAMPLE_PROJECT.csproj
SccLocalPath1 = ..
SccProjectFilePathRelativizedFromConnection1 = P4SCC_SAMPLE_PROJECT\\
SccProjectUniqueName2 = ..\\Forms_Project\\Forms_Project.csproj
SccLocalPath2 = ..
SccProjectFilePathRelativizedFromConnection2 = Forms_Project\\
EndGlobalSection
You must remove these lines from the solution file. These lines may occur multiple
times in the file: once for the solution and additional times for one or more
projects. Each instance of the text must be removed.
Project files contain the following lines (usually in the first "PropertyGroup"):
SAK
SAK
SAK
SAK
Again, these lines need to be removed from the project file. The project file
might not include all four lines, but whatever lines are present should be removed.
Note that you can remove P4SCC bindings manually or with the help of the utility
provided below. Either way, you must ensure that all bindings and source-control-
specific files are gone.
The following command line utility may be used to help with the migration. It is
written in C#.NET:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MigrateP4SccToP4VS
{
///
/// Simple command line utility to strip the source control bindings from solution and project files
///
///
/// MigrateP4SccToP4VS path1 [path2] ...[pathn]]
///
///
/// Solution files are assumed to have the extension "sln".
/// Project files are assumed to have the extensions containing "proj" (i.e csproj, vcxproj, ...).
///
/// Creates a backup of the original file with "-p4scc" added to the file name before the extension.
///
class Program
{
static void Main(string[] args)
{
foreach (string path in args)
{
if (File.Exists(path) == false)
{
Console.WriteLine("Can't' find file, {0}", path);
continue;
}
string fileExtension = Path.GetExtension(path);
string copyPath = Path.Combine(
Path.GetDirectoryName(path),
string.Format("{0}-p4scc{1}", Path.GetFileNameWithoutExtension(path), fileExtension));
if (fileExtension.ToLower().EndsWith("sln"))
{
Console.WriteLine("Processing solution file, {0}", path);
FileInfo info = new FileInfo(path);
if (info.IsReadOnly)
{
info.IsReadOnly = false;
}
if (File.Exists(copyPath) == false)
{
// if not already copied, make a backup
File.Move(path, copyPath);
}
using (StreamReader sr = new StreamReader(copyPath,true))
{
Encoding encode = sr.CurrentEncoding;
using (StreamWriter sw = new StreamWriter(path, false, encode))
{
string line = null;
while ((line = sr.ReadLine()) != null)
{
if (line.Trim().StartsWith("GlobalSection(SourceCodeControl)"))
{
while (((line = sr.ReadLine()) != null) && (line.Contains("EndGlobalSection") == false))
{
// don't copy
}
}
else
{
sw.WriteLine(line);
}
}
}
}
}
else if (fileExtension.ToLower().Contains("proj"))
{
Console.WriteLine("Processing project file, {0}", path);
FileInfo info = new FileInfo(path);
if (info.IsReadOnly)
{
info.IsReadOnly = false;
}
if (File.Exists(copyPath) == false)
{
// if not already copied, make a backup
File.Move(path, copyPath);
}
using (StreamReader sr = new StreamReader(copyPath, true))
{
Encoding encode = sr.CurrentEncoding;
using (StreamWriter sw = new StreamWriter(path, false,encode))
{
string line = null;
while ((line = sr.ReadLine()) != null)
{
if ((line.Contains("SccProjectName>") == false) &&
(line.Contains("SccLocalPath>") == false) &&
(line.Contains("SccAuxPath>") == false) &&
(line.Contains("SccProvider>") == false))
{
// only copy lines that aren't part of the bindings
sw.WriteLine(line);
}
}
}
}
}
}
}
}
}