开发者

How do I make a Visual Studio 2010 solution read-only?

How do I make a 开发者_运维技巧Visual Studio 2010 solution read-only?


You have to set the solution (and all other files that you want to protect) to read-only on the operating system level. So for windows select the files, then right click, select properties and then check the read-only check box. The read-only annotation shows up when you are reloading the project. To make the solution/project writeable just uncheck the read-only checkbox.

Note: When setting the solution to read-only, you cannot add any new projects to it, however, the projects remain writeable.


In your comment you said you want to lock your source code. You can "read-only" lock your code with this console program. You can also unlock and tersely query what is locked. It is handy for Visual Studio. It can lock everything because it is recursive and then you would just unlock the single solution you are working on.

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);
        }
    }
}

The suggested batch file with a terse name is lock.bat and can serve to invoke the above program.

@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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜