如何将Visual Studio 2010解决方案设为只读?
答案 0 :(得分:2)
您必须在操作系统级别将解决方案(以及您要保护的所有其他文件)设置为只读。因此,对于Windows选择文件,然后右键单击,选择属性,然后选中只读复选框。重新加载项目时会显示只读注释。要使解决方案/项目可写,只需取消选中只读复选框。
注意:将解决方案设置为只读时,无法向其添加任何新项目,但项目仍然可写。
答案 1 :(得分:0)
在评论中,您说要锁定源代码。您可以使用此控制台程序“只读”锁定代码。您还可以解锁并简洁地查询锁定的内容。它对Visual Studio很方便。它可以锁定所有内容,因为它是递归的,然后您只需解锁您正在处理的单个解决方案。
namespace SourceLocker1
{
// lock source code by setting read only for all files that match source file extensions
class Program
{
internal const bool VerboseMode = false;
internal const int ShowImmediateLevelDefault = 3;
internal static List<string> FileNameExtensions = new List<string> { ".c", ".cpp", ".cs", ".xaml", ".java", ".py" };
internal enum Mode { SetReadOnly = 0, UnSetReadOnly, Show };
static void Main(string[] args)
{
if ((args.Length != 1) && (args.Length != 2))
Program.PrintUsage();
else if (args.Length == 1)
Program.RecursiveTraverse(Mode.SetReadOnly, args[0]); // program.exe path
else if ((args.Length == 2) && (args[0] == "u"))
Program.RecursiveTraverse(Mode.UnSetReadOnly, args[1]); // program.exe u path
else if ((args.Length == 2) && (args[0] == "s"))
Program.RecursiveTraverse(Mode.Show, args[1]); // program.exe s path
else if ((args.Length == 2) && (args[0] == "si"))
Program.ImmediateModeShowFirstNotReadOnly(Program.ShowImmediateLevelDefault, args[1]); // program.exe si path
else if ((args.Length == 2) && (args[0] == "si1"))
Program.ImmediateModeShowFirstNotReadOnly(1, args[1]); // program.exe si1 path
else if ((args.Length == 2) && (args[0] == "si2"))
Program.ImmediateModeShowFirstNotReadOnly(2, args[1]); // program.exe si2 path
else if ((args.Length == 2) && (args[0] == "si3"))
Program.ImmediateModeShowFirstNotReadOnly(3, args[1]); // program.exe si3 path
else
Program.PrintUsage();
}
static void RecursiveTraverse(Mode mode, string path)
{
IEnumerable<string> filePaths;
if (Directory.Exists(path))
{
filePaths = Directory.EnumerateFiles(path);
// recurse here
foreach (string directoryPath in Directory.EnumerateDirectories(path))
Program.RecursiveTraverse(mode, directoryPath);
}
else
{
if (File.Exists(path))
{
// Array is IEnumerable<T> Read the manual carefully
filePaths = new string[1] { path };
}
else
{
filePaths = new string[0]; // empty array
Console.WriteLine("Not found: {0}", path);
}
}
Program.ProcessFilePaths(mode, filePaths);
}
// immediate mode searches in the immediate levels
// and limits the output to one file per level
// level 1: files in the folder path
// level 2: files in the sub folder paths
// level 3: files in the sub sub folder paths
static void ImmediateModeShowFirstNotReadOnly(int showImmediateLevel, string folderPath)
{
if (Directory.Exists(folderPath))
{
if (showImmediateLevel >= 1)
{
Program.ShowFirstNotReadOnly(Directory.GetFiles(folderPath)); // first level
if (showImmediateLevel > 1)
{
foreach (string subFolderPath in Directory.EnumerateDirectories(folderPath))
{
if (showImmediateLevel >= 2)
{
Program.ShowFirstNotReadOnly(Directory.GetFiles(subFolderPath)); // second level
if (showImmediateLevel > 2)
{
foreach (string subSubFolderPath in Directory.EnumerateDirectories(subFolderPath))
{
if (showImmediateLevel >= 3)
Program.ShowFirstNotReadOnly(Directory.GetFiles(subSubFolderPath)); // third level
}
}
}
}
}
}
}
else
{
Console.WriteLine("No such folder: {0}", folderPath);
}
}
static void PrintUsage()
{
Console.WriteLine("Examples:");
Console.WriteLine(" sourcelocker1 FileName.cs");
Console.WriteLine(" sourcelocker1 FolderName");
Console.WriteLine(" sourcelocker1 u FileName.cs");
Console.WriteLine(" sourcelocker1 u FolderName");
Console.WriteLine(" sourcelocker1 s FileName.cs");
Console.WriteLine(" sourcelocker1 s FolderName");
Console.WriteLine(" Also");
Console.WriteLine(" sourcelocker1 si FolderName");
Console.WriteLine(" sourcelocker1 si1 FolderName");
Console.WriteLine(" sourcelocker1 si2 FolderName");
Console.WriteLine(" sourcelocker1 si3 FolderName");
Console.WriteLine("Usage:");
Console.WriteLine(" This program makes files read-only or not-read-only.");
Console.WriteLine(" This program is recursive or immediate depending upon the mode.");
Console.WriteLine(" By default this program is recursive.");
Console.WriteLine(@" ""u"" means unlock");
Console.WriteLine(@" ""s"" means show unlocked matching files");
Console.WriteLine(@" ""si"" means show unlocked matching files in the ""si3"" immediate mode");
Console.WriteLine(" Immediate mode is an n-level search, abbreviated to one file per folder.");
Console.WriteLine(" Immediate mode can be useful in a Projects folder where");
Console.WriteLine(@" the structure is like Projects\Project1\Source and Projects\Project2\Source");
Console.WriteLine(@" in which case if the path argument is ""Projects"" .cs files may be found at:");
Console.WriteLine(@" Projects\*.cs");
Console.WriteLine(@" Projects\Project1\*.cs");
Console.WriteLine(@" Projects\Project1\Source\*.cs");
Console.WriteLine(@" Projects\Project2\*.cs");
Console.WriteLine(@" Projects\Project2\Source\*.cs");
Console.WriteLine("Supported extension types:");
Console.Write(" ");
IEnumerator e = Program.FileNameExtensions.GetEnumerator();
e.Reset();
while (e.MoveNext())
Console.Write("{0} ", e.Current);
Console.WriteLine();
}
static void ProcessFilePaths(Mode mode, IEnumerable<string> filePaths)
{
foreach (string filePath in filePaths)
{
foreach (string extension in Program.FileNameExtensions)
{
if (filePath.EndsWith(extension, StringComparison.CurrentCultureIgnoreCase))
{
if (mode == Mode.SetReadOnly)
Program.SetFileReadOnly(filePath);
else if (mode == Mode.UnSetReadOnly)
Program.UnSetFileReadOnly(filePath);
else if (mode == Mode.Show)
Program.ShowReadOnlyAttribute(filePath);
else
Debug.Assert(false);
}
}
}
}
static void SetFileReadOnly(string filePath)
{
// FileAttributes is a [FlagsAttribute] modified enum in powers of 2,
// and as such, it can take bitwise operations
VerboseConsole.WriteLine(filePath + " set read only");
File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.ReadOnly);
}
static void UnSetFileReadOnly(string filePath)
{
// FileAttributes is a [FlagsAttribute] modified enum in powers of 2,
// and as such, it can take bitwise operations
VerboseConsole.WriteLine(filePath + " unset read only");
File.SetAttributes(filePath, File.GetAttributes(filePath) & (~FileAttributes.ReadOnly));
}
static void ShowReadOnlyAttribute(string filePath)
{
bool bit = (File.GetAttributes(filePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly;
if (bit)
VerboseConsole.WriteLine(filePath + " is read only");
else
Console.WriteLine(filePath + " is NOT read only");
}
// shows the first file path that is not read only
// returns silently if there are none
static void ShowFirstNotReadOnly(IEnumerable<string> filePaths)
{
foreach (string filePath in filePaths)
foreach (string extension in Program.FileNameExtensions)
if (filePath.EndsWith(extension, StringComparison.CurrentCultureIgnoreCase) &&
(Program.IsReadOnly(filePath) == false))
{
Console.WriteLine(filePath + " is NOT read only");
return;
}
}
static bool IsReadOnly(string filePath)
{
return (File.GetAttributes(filePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly;
}
}
internal static class VerboseConsole
{
internal static void Write(string arg)
{
if (Program.VerboseMode) Console.Write(arg);
}
internal static void Write(string arg, object[] args)
{
if (Program.VerboseMode) Console.Write(arg, args);
}
internal static void WriteLine(string arg)
{
if (Program.VerboseMode) Console.WriteLine(arg);
}
internal static void WriteLine(string arg, object[] args)
{
if (Program.VerboseMode) Console.WriteLine(arg, args);
}
}
}
建议的批处理文件名称为lock.bat
,可用于调用上述程序。
@REM Commands prefaced with @ have echo suppressed.
@REM
@REM The program sourcelocker1.exe supports only 1 or 2 arguments but we pass 3 just
@REM to verify that usage information is printed in this case of misuse.
@REM
@sourcelocker1.exe %1 %2 %3