Index: obsolete/Microsoft.VisualStudio.Project/Utilities.cs |
diff --git a/obsolete/Microsoft.VisualStudio.Project/Utilities.cs b/obsolete/Microsoft.VisualStudio.Project/Utilities.cs |
deleted file mode 100644 |
index f542fd8be3b1f01e25c399e63c501920d3948b56..0000000000000000000000000000000000000000 |
--- a/obsolete/Microsoft.VisualStudio.Project/Utilities.cs |
+++ /dev/null |
@@ -1,1020 +0,0 @@ |
-/// Copyright (c) Microsoft Corporation. All rights reserved. |
- |
-using System; |
-using System.Collections.Generic; |
-using System.ComponentModel; |
-using System.Diagnostics; |
-using System.Diagnostics.CodeAnalysis; |
-using System.Drawing; |
-using System.Globalization; |
-using System.IO; |
-using System.Runtime.InteropServices; |
-using System.Security.Permissions; |
-using System.Security.Policy; |
-using System.Text; |
-using System.Text.RegularExpressions; |
-using System.Windows.Forms; |
-using Microsoft.VisualStudio; |
-using Microsoft.VisualStudio.OLE.Interop; |
-using Microsoft.VisualStudio.Shell; |
-using Microsoft.VisualStudio.Shell.Interop; |
-using Microsoft.Win32; |
-using IServiceProvider = System.IServiceProvider; |
-using MSBuild = Microsoft.Build.BuildEngine; |
-using VSRegistry = Microsoft.VisualStudio.Shell.VSRegistry; |
- |
-namespace Microsoft.VisualStudio.Project |
-{ |
- public static class Utilities |
- { |
- private const string defaultMSBuildVersion = "2.0"; |
- |
- /// <summary> |
- /// Look in the registry under the current hive for the path |
- /// of MSBuild |
- /// </summary> |
- /// <returns></returns> |
- [CLSCompliant(false)] |
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ms")] |
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "msbuild")] |
- public static string GetMsBuildPath(IServiceProvider serviceProvider) |
- { |
- return GetMsBuildPath(serviceProvider, defaultMSBuildVersion); |
- } |
- |
- /// <summary> |
- /// Search the registry for the tools path for MSBuild. |
- /// </summary> |
- /// <param name="serviceProvider">The service provider.</param> |
- /// <param name="version">Msbuild version.</param> |
- /// <returns>The msbuild tools path</returns> |
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ms")] |
- public static string GetMsBuildPath(IServiceProvider serviceProvider, string version) |
- { |
- string msBuildPath = null; |
- using(RegistryKey root = VSRegistry.RegistryRoot(serviceProvider, __VsLocalRegistryType.RegType_Configuration, false)) |
- { |
- // Get the value from the registry |
- using(RegistryKey vsKey = root.OpenSubKey("MSBuild", false)) |
- { |
- msBuildPath = (string)vsKey.GetValue("MSBuildBinPath", null); |
- } |
- } |
- if(!string.IsNullOrEmpty(msBuildPath)) |
- { |
- return msBuildPath; |
- } |
- |
- // The path to MSBuild was not found in the VisualStudio's registry hive, so try to |
- // find it in the new MSBuild hive. |
- string registryPath = string.Format(CultureInfo.InvariantCulture, "Software\\Microsoft\\MSBuild\\ToolsVersions\\{0}", version); |
- using(Microsoft.Win32.RegistryKey msbuildKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(registryPath, false)) |
- { |
- msBuildPath = (string)msbuildKey.GetValue("MSBuildToolsPath", null); |
- } |
- if(string.IsNullOrEmpty(msBuildPath)) |
- { |
- string error = SR.GetString(SR.ErrorMsBuildRegistration, CultureInfo.CurrentUICulture); |
- throw new FileLoadException(error); |
- } |
- return msBuildPath; |
- } |
- |
- /// <summary> |
- /// Is Visual Studio in design mode. |
- /// </summary> |
- /// <param name="serviceProvider">The service provider.</param> |
- /// <returns>true if visual studio is in design mode</returns> |
- public static bool IsVisualStudioInDesignMode(IServiceProvider site) |
- { |
- IVsMonitorSelection selectionMonitor = site.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection; |
- uint cookie = 0; |
- int active = 0; |
- Guid designContext = VSConstants.UICONTEXT_DesignMode; |
- ErrorHandler.ThrowOnFailure(selectionMonitor.GetCmdUIContextCookie(ref designContext, out cookie)); |
- ErrorHandler.ThrowOnFailure(selectionMonitor.IsCmdUIContextActive(cookie, out active)); |
- return active != 0; |
- } |
- |
- /// <include file='doc\VsShellUtilities.uex' path='docs/doc[@for="Utilities.IsInAutomationFunction"]/*' /> |
- /// <devdoc> |
- /// Is an extensibility object executing an automation function. |
- /// </devdoc> |
- /// <param name="serviceProvider">The service provider.</param> |
- /// <returns>true if the extensiblity object is executing an automation function.</returns> |
- public static bool IsInAutomationFunction(IServiceProvider serviceProvider) |
- { |
- if(serviceProvider == null) |
- { |
- throw new ArgumentNullException("serviceProvider"); |
- } |
- |
- IVsExtensibility3 extensibility = serviceProvider.GetService(typeof(EnvDTE.IVsExtensibility)) as IVsExtensibility3; |
- |
- if(extensibility == null) |
- { |
- throw new InvalidOperationException(); |
- } |
- int inAutomation = 0; |
- ErrorHandler.ThrowOnFailure(extensibility.IsInAutomationFunction(out inAutomation)); |
- return inAutomation != 0; |
- } |
- |
- /// <summary> |
- /// Creates a semicolon delinited list of strings. This can be used to provide the properties for VSHPROPID_CfgPropertyPagesCLSIDList, VSHPROPID_PropertyPagesCLSIDList, VSHPROPID_PriorityPropertyPagesCLSIDList |
- /// </summary> |
- /// <param name="guids">An array of Guids.</param> |
- /// <returns>A semicolon delimited string, or null</returns> |
- [CLSCompliant(false)] |
- public static string CreateSemicolonDelimitedListOfStringFromGuids(Guid[] guids) |
- { |
- if(guids == null || guids.Length == 0) |
- { |
- return null; |
- } |
- |
- // Create a StringBuilder with a pre-allocated buffer big enough for the |
- // final string. 39 is the length of a GUID in the "B" form plus the final ';' |
- StringBuilder stringList = new StringBuilder(39 * guids.Length); |
- for(int i = 0; i < guids.Length; i++) |
- { |
- stringList.Append(guids[i].ToString("B")); |
- stringList.Append(";"); |
- } |
- |
- return stringList.ToString().TrimEnd(';'); |
- } |
- |
- private static char[] curlyBraces = new char[] { '{', '}' }; |
- /// <summary> |
- /// Take list of guids as a single string and generate an array of Guids from it |
- /// </summary> |
- /// <param name="guidList">Semi-colon separated list of Guids</param> |
- /// <returns>Array of Guids</returns> |
- [CLSCompliant(false)] |
- public static Guid[] GuidsArrayFromSemicolonDelimitedStringOfGuids(string guidList) |
- { |
- if(guidList == null) |
- { |
- return null; |
- } |
- |
- List<Guid> guids = new List<Guid>(); |
- string[] guidsStrings = guidList.Split(';'); |
- foreach(string guid in guidsStrings) |
- { |
- if(!String.IsNullOrEmpty(guid)) |
- guids.Add(new Guid(guid.Trim(curlyBraces))); |
- } |
- |
- return guids.ToArray(); |
- } |
- |
- /// <summary> |
- /// Validates a file path by validating all file parts. If the |
- /// the file name is invalid it throws an exception if the project is in automation. Otherwise it shows a dialog box with the error message. |
- /// </summary> |
- /// <param name="serviceProvider">The service provider</param> |
- /// <param name="filePath">A full path to a file name</param> |
- /// <exception cref="InvalidOperationException">In case of failure an InvalidOperationException is thrown.</exception> |
- public static void ValidateFileName(IServiceProvider serviceProvider, string filePath) |
- { |
- string errorMessage = String.Empty; |
- if(String.IsNullOrEmpty(filePath)) |
- { |
- errorMessage = SR.GetString(SR.ErrorInvalidFileName, CultureInfo.CurrentUICulture); |
- } |
- else if(filePath.Length > NativeMethods.MAX_PATH) |
- { |
- errorMessage = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.PathTooLong, CultureInfo.CurrentUICulture), filePath); |
- } |
- else if(ContainsInvalidFileNameChars(filePath)) |
- { |
- errorMessage = SR.GetString(SR.ErrorInvalidFileName, CultureInfo.CurrentUICulture); |
- } |
- |
- if(errorMessage.Length == 0) |
- { |
- string fileName = Path.GetFileName(filePath); |
- if(String.IsNullOrEmpty(fileName) || IsFileNameInvalid(fileName)) |
- { |
- errorMessage = SR.GetString(SR.ErrorInvalidFileName, CultureInfo.CurrentUICulture); |
- } |
- else |
- { |
- string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); |
- |
- // If there is no filename or it starts with a leading dot issue an error message and quit. |
- if(String.IsNullOrEmpty(fileNameWithoutExtension) || fileNameWithoutExtension[0] == '.') |
- { |
- errorMessage = SR.GetString(SR.FileNameCannotContainALeadingPeriod, CultureInfo.CurrentUICulture); |
- } |
- } |
- } |
- |
- if(errorMessage.Length > 0) |
- { |
- // If it is not called from an automation method show a dialog box. |
- if(!Utilities.IsInAutomationFunction(serviceProvider)) |
- { |
- string title = null; |
- OLEMSGICON icon = OLEMSGICON.OLEMSGICON_CRITICAL; |
- OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_OK; |
- OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST; |
- VsShellUtilities.ShowMessageBox(serviceProvider, title, errorMessage, icon, buttons, defaultButton); |
- } |
- else |
- { |
- throw new InvalidOperationException(errorMessage); |
- } |
- } |
- |
- } |
- |
- /// <summary> |
- /// Creates a CALPOLESTR from a list of strings |
- /// It is the responsability of the caller to release this memory. |
- /// </summary> |
- /// <param name="guids"></param> |
- /// <returns>A CALPOLESTR that was created from the the list of strings.</returns> |
- [CLSCompliant(false)] |
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "CALPOLESTR")] |
- public static CALPOLESTR CreateCALPOLESTR(IList<string> strings) |
- { |
- CALPOLESTR calpolStr = new CALPOLESTR(); |
- |
- if(strings != null) |
- { |
- // Demand unmanaged permissions in order to access unmanaged memory. |
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); |
- |
- calpolStr.cElems = (uint)strings.Count; |
- |
- int size = Marshal.SizeOf(typeof(IntPtr)); |
- |
- calpolStr.pElems = Marshal.AllocCoTaskMem(strings.Count * size); |
- |
- IntPtr ptr = calpolStr.pElems; |
- |
- foreach(string aString in strings) |
- { |
- IntPtr tempPtr = Marshal.StringToCoTaskMemUni(aString); |
- Marshal.WriteIntPtr(ptr, tempPtr); |
- ptr = new IntPtr(ptr.ToInt64() + size); |
- } |
- } |
- |
- return calpolStr; |
- } |
- |
- /// <summary> |
- /// Creates a CADWORD from a list of tagVsSccFilesFlags. Memory is allocated for the elems. |
- /// It is the responsability of the caller to release this memory. |
- /// </summary> |
- /// <param name="guids"></param> |
- /// <returns>A CADWORD created from the list of tagVsSccFilesFlags.</returns> |
- [CLSCompliant(false)] |
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "CADWORD")] |
- public static CADWORD CreateCADWORD(IList<tagVsSccFilesFlags> flags) |
- { |
- CADWORD cadWord = new CADWORD(); |
- |
- if(flags != null) |
- { |
- // Demand unmanaged permissions in order to access unmanaged memory. |
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); |
- |
- cadWord.cElems = (uint)flags.Count; |
- |
- int size = Marshal.SizeOf(typeof(UInt32)); |
- |
- cadWord.pElems = Marshal.AllocCoTaskMem(flags.Count * size); |
- |
- IntPtr ptr = cadWord.pElems; |
- |
- foreach(tagVsSccFilesFlags flag in flags) |
- { |
- Marshal.WriteInt32(ptr, (int)flag); |
- ptr = new IntPtr(ptr.ToInt64() + size); |
- } |
- } |
- |
- return cadWord; |
- } |
- |
- /// <summary> |
- /// Splits a bitmap from a Stream into an ImageList |
- /// </summary> |
- /// <param name="imageStream">A Stream representing a Bitmap</param> |
- /// <returns>An ImageList object representing the images from the given stream</returns> |
- public static ImageList GetImageList(Stream imageStream) |
- { |
- ImageList ilist = new ImageList(); |
- |
- if(imageStream == null) |
- { |
- return ilist; |
- } |
- ilist.ColorDepth = ColorDepth.Depth24Bit; |
- ilist.ImageSize = new Size(16, 16); |
- Bitmap bitmap = new Bitmap(imageStream); |
- ilist.Images.AddStrip(bitmap); |
- ilist.TransparentColor = Color.Magenta; |
- return ilist; |
- } |
- |
- /// <summary> |
- /// Splits a bitmap from a pointer to an ImageList |
- /// </summary> |
- /// <param name="imageListAsPointer">A pointer to a bitmap of images to split</param> |
- /// <returns>An ImageList object representing the images from the given stream</returns> |
- public static ImageList GetImageList(object imageListAsPointer) |
- { |
- ImageList images = null; |
- |
- IntPtr intPtr = new IntPtr((int)imageListAsPointer); |
- HandleRef hImageList = new HandleRef(null, intPtr); |
- int count = UnsafeNativeMethods.ImageList_GetImageCount(hImageList); |
- |
- if(count > 0) |
- { |
- // Create a bitmap big enough to hold all the images |
- Bitmap b = new Bitmap(16 * count, 16); |
- Graphics g = Graphics.FromImage(b); |
- |
- // Loop through and extract each image from the imagelist into our own bitmap |
- IntPtr hDC = IntPtr.Zero; |
- try |
- { |
- hDC = g.GetHdc(); |
- HandleRef handleRefDC = new HandleRef(null, hDC); |
- for(int i = 0; i < count; i++) |
- { |
- UnsafeNativeMethods.ImageList_Draw(hImageList, i, handleRefDC, i * 16, 0, NativeMethods.ILD_NORMAL); |
- } |
- } |
- finally |
- { |
- if(g != null && hDC != IntPtr.Zero) |
- { |
- g.ReleaseHdc(hDC); |
- } |
- } |
- |
- // Create a new imagelist based on our stolen images |
- images = new ImageList(); |
- images.ColorDepth = ColorDepth.Depth24Bit; |
- images.ImageSize = new Size(16, 16); |
- images.Images.AddStrip(b); |
- } |
- return images; |
- } |
- |
- /// <summary> |
- /// Gets the active configuration name. |
- /// </summary> |
- /// <param name="automationObject">The automation object.</param> |
- /// <returns>The name of the active configuartion.</returns> |
- internal static string GetActiveConfigurationName(EnvDTE.Project automationObject) |
- { |
- if(automationObject == null) |
- { |
- throw new ArgumentNullException("automationObject"); |
- } |
- |
- string currentConfigName = string.Empty; |
- if(automationObject.ConfigurationManager != null) |
- { |
- EnvDTE.Configuration activeConfig = automationObject.ConfigurationManager.ActiveConfiguration; |
- if(activeConfig != null) |
- { |
- currentConfigName = activeConfig.ConfigurationName; |
- } |
- } |
- return currentConfigName; |
- |
- } |
- |
- |
- /// <summary> |
- /// Verifies that two objects represent the same instance of a COM object. |
- /// This essentially compares the IUnkown pointers of the 2 objects. |
- /// This is needed in scenario where aggregation is involved. |
- /// </summary> |
- /// <param name="obj1">Can be an object, interface or IntPtr</param> |
- /// <param name="obj2">Can be an object, interface or IntPtr</param> |
- /// <returns>True if the 2 items represent the same thing</returns> |
- [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj")] |
- public static bool IsSameComObject(object obj1, object obj2) |
- { |
- bool isSame = false; |
- IntPtr unknown1 = IntPtr.Zero; |
- IntPtr unknown2 = IntPtr.Zero; |
- try |
- { |
- // If we have 2 null, then they are not COM objects and as such "it's not the same COM object" |
- if(obj1 != null && obj2 != null) |
- { |
- unknown1 = QueryInterfaceIUnknown(obj1); |
- unknown2 = QueryInterfaceIUnknown(obj2); |
- |
- isSame = IntPtr.Equals(unknown1, unknown2); |
- } |
- } |
- finally |
- { |
- if(unknown1 != IntPtr.Zero) |
- { |
- Marshal.Release(unknown1); |
- } |
- |
- if(unknown2 != IntPtr.Zero) |
- { |
- Marshal.Release(unknown2); |
- } |
- |
- } |
- |
- return isSame; |
- } |
- |
- /// <summary> |
- /// Retrieve the IUnknown for the managed or COM object passed in. |
- /// </summary> |
- /// <param name="objToQuery">Managed or COM object.</param> |
- /// <returns>Pointer to the IUnknown interface of the object.</returns> |
- internal static IntPtr QueryInterfaceIUnknown(object objToQuery) |
- { |
- bool releaseIt = false; |
- IntPtr unknown = IntPtr.Zero; |
- IntPtr result; |
- try |
- { |
- if(objToQuery is IntPtr) |
- { |
- unknown = (IntPtr)objToQuery; |
- } |
- else |
- { |
- // This is a managed object (or RCW) |
- unknown = Marshal.GetIUnknownForObject(objToQuery); |
- releaseIt = true; |
- } |
- |
- // We might already have an IUnknown, but if this is an aggregated |
- // object, it may not be THE IUnknown until we QI for it. |
- Guid IID_IUnknown = VSConstants.IID_IUnknown; |
- ErrorHandler.ThrowOnFailure(Marshal.QueryInterface(unknown, ref IID_IUnknown, out result)); |
- } |
- finally |
- { |
- if(releaseIt && unknown != IntPtr.Zero) |
- { |
- Marshal.Release(unknown); |
- } |
- |
- } |
- |
- return result; |
- } |
- |
- /// <summary> |
- /// Returns true if thename that can represent a path, absolut or relative, or a file name contains invalid filename characters. |
- /// </summary> |
- /// <param name="name">File name</param> |
- /// <returns>true if file name is invalid</returns> |
- public static bool ContainsInvalidFileNameChars(string name) |
- { |
- if(String.IsNullOrEmpty(name)) |
- { |
- return true; |
- } |
- |
- try |
- { |
- if(Path.IsPathRooted(name) && !name.StartsWith(@"\\", StringComparison.Ordinal)) |
- { |
- string root = Path.GetPathRoot(name); |
- name = name.Substring(root.Length); |
- } |
- } |
- // The Path methods used by ContainsInvalidFileNameChars return argument exception if the filePath contains invalid characters. |
- catch(ArgumentException) |
- { |
- return true; |
- } |
- |
- Microsoft.VisualStudio.Shell.Url uri = new Microsoft.VisualStudio.Shell.Url(name); |
- |
- // This might be confusing bur Url.IsFile means that the uri represented by the name is either absolut or relative. |
- if(uri.IsFile) |
- { |
- string[] segments = uri.Segments; |
- if(segments != null && segments.Length > 0) |
- { |
- foreach(string segment in segments) |
- { |
- if(IsFilePartInValid(segment)) |
- { |
- return true; |
- } |
- } |
- |
- // Now the last segment should be specially taken care, since that cannot be all dots or spaces. |
- string lastSegment = segments[segments.Length - 1]; |
- string filePart = Path.GetFileNameWithoutExtension(lastSegment); |
- if(IsFileNameAllGivenCharacter('.', filePart) || IsFileNameAllGivenCharacter(' ', filePart)) |
- { |
- return true; |
- } |
- } |
- } |
- else |
- { |
- // The assumption here is that we got a file name. |
- string filePart = Path.GetFileNameWithoutExtension(name); |
- if(IsFileNameAllGivenCharacter('.', filePart) || IsFileNameAllGivenCharacter(' ', filePart)) |
- { |
- return true; |
- } |
- |
- |
- return IsFilePartInValid(name); |
- } |
- |
- return false; |
- } |
- |
- /// Cehcks if a file name is valid. |
- /// </devdoc> |
- /// <param name="fileName">The name of the file</param> |
- /// <returns>True if the file is valid.</returns> |
- public static bool IsFileNameInvalid(string fileName) |
- { |
- if(String.IsNullOrEmpty(fileName)) |
- { |
- return true; |
- } |
- |
- if(IsFileNameAllGivenCharacter('.', fileName) || IsFileNameAllGivenCharacter(' ', fileName)) |
- { |
- return true; |
- } |
- |
- |
- return IsFilePartInValid(fileName); |
- |
- } |
- |
- /// <summary> |
- /// Helper method to call a converter explicitely to convert to an enum type |
- /// </summary> |
- /// <typeparam name="T">THe enum to convert to</typeparam> |
- /// <typeparam name="V">The converter that will be created</typeparam> |
- /// <param name="value">The enum value to be converted to</param> |
- /// <param name="typeToConvert">The type to convert</param> |
- /// <param name="culture">The culture to use to read the localized strings</param> |
- /// <returns></returns> |
- [CLSCompliant(false)] |
- public static object ConvertToType<T>(T value, Type typeToConvert, CultureInfo culture) |
- where T : struct |
- { |
- EnumConverter converter = GetEnumConverter<T>(); |
- if(converter == null) |
- { |
- return null; |
- } |
- if(converter.CanConvertTo(typeToConvert)) |
- { |
- return converter.ConvertTo(null, culture, value, typeToConvert); |
- } |
- |
- return null; |
- } |
- |
- /// <summary> |
- /// Helper method for converting from a string to an enum using a converter. |
- /// </summary> |
- /// <typeparam name="T"></typeparam> |
- /// <param name="value"></param> |
- /// <param name="culture">The culture to use to read the localized strings</param> |
- /// <returns></returns> |
- [CLSCompliant(false)] |
- public static Nullable<T> ConvertFromType<T>(string value, CultureInfo culture) |
- where T : struct |
- { |
- Nullable<T> returnValue = new Nullable<T>(); |
- |
- returnValue = returnValue.GetValueOrDefault(); |
- |
- if(value == null) |
- { |
- return returnValue; |
- } |
- |
- EnumConverter converter = GetEnumConverter<T>(); |
- if(converter == null) |
- { |
- return returnValue; |
- } |
- |
- if(converter.CanConvertFrom(value.GetType())) |
- { |
- object converted = converter.ConvertFrom(null, culture, value); |
- |
- if(converted != null && (converted is T)) |
- { |
- returnValue = (T)converted; |
- } |
- } |
- |
- return returnValue; |
- } |
- |
- |
- /// <summary> |
- /// Sets a string value from an enum |
- /// </summary> |
- /// <typeparam name="T">The enum type</typeparam> |
- /// <param name="enumValue">The value of teh enum.</param> |
- /// <returns></returns> |
- [CLSCompliant(false)] |
- public static string SetStringValueFromConvertedEnum<T>(T enumValue, CultureInfo culture) |
- where T : struct |
- { |
- string convertToType = ConvertToType<T>(enumValue, typeof(string), culture) as string; |
- |
- if(convertToType == null) |
- { |
- return String.Empty; |
- } |
- |
- return convertToType; |
- } |
- |
- |
- /// <summary> |
- /// Initializes the in memory project. Sets BuildEnabled on the project to true. |
- /// </summary> |
- /// <param name="engine">The build engine to use to create a build project.</param> |
- /// <param name="fullProjectPath">The full path of the project.</param> |
- /// <returns>A loaded msbuild project.</returns> |
- internal static MSBuild.Project InitializeMsBuildProject(MSBuild.Engine buildEngine, string fullProjectPath) |
- { |
- if(buildEngine == null) |
- { |
- throw new ArgumentNullException("buildEngine"); |
- } |
- |
- if(String.IsNullOrEmpty(fullProjectPath)) |
- { |
- throw new ArgumentException(SR.GetString(SR.InvalidParameter, CultureInfo.CurrentUICulture), "fullProjectPath"); |
- } |
- |
- // Check if the project already has been loaded with the fullProjectPath. If yes return the build project associated to it. |
- MSBuild.Project buildProject = buildEngine.GetLoadedProject(fullProjectPath); |
- |
- if(buildProject == null) |
- { |
- buildProject = buildEngine.CreateNewProject(); |
- buildProject.BuildEnabled = true; |
- buildProject.Load(fullProjectPath); |
- } |
- |
- return buildProject; |
- } |
- |
- /// <summary> |
- /// Loads a project file for the file. If the build project exists and it was loaded with a different file then it is unloaded first. |
- /// </summary> |
- /// <param name="engine">The build engine to use to create a build project.</param> |
- /// <param name="fullProjectPath">The full path of the project.</param> |
- /// <param name="exitingBuildProject">An Existing build project that will be reloaded.</param> |
- /// <returns>A loaded msbuild project.</returns> |
- internal static MSBuild.Project ReinitializeMsBuildProject(MSBuild.Engine buildEngine, string fullProjectPath, MSBuild.Project exitingBuildProject) |
- { |
- // If we have a build project that has been loaded with another file unload it. |
- try |
- { |
- if(exitingBuildProject != null && exitingBuildProject.ParentEngine != null && !NativeMethods.IsSamePath(exitingBuildProject.FullFileName, fullProjectPath)) |
- { |
- exitingBuildProject.ParentEngine.UnloadProject(exitingBuildProject); |
- } |
- } |
- // We catch Invalid operation exception because if the project was unloaded while we touch the ParentEngine the msbuild API throws. |
- // Is there a way to figure out that a project was unloaded? |
- catch(InvalidOperationException) |
- { |
- } |
- |
- return Utilities.InitializeMsBuildProject(buildEngine, fullProjectPath); |
- } |
- |
- /// <summary> |
- /// Initialize the build engine. Sets the build enabled property to true. The engine is initialzed if the passed in engine is null or does not have its bin path set. |
- /// </summary> |
- /// <param name="engine">An instance of MSBuild.Engine build engine, that will be checked if initialized.</param> |
- /// <param name="engine">The service provider.</param> |
- /// <returns>The buildengine to use.</returns> |
- internal static MSBuild.Engine InitializeMsBuildEngine(MSBuild.Engine existingEngine, IServiceProvider serviceProvider) |
- { |
- if(serviceProvider == null) |
- { |
- throw new ArgumentNullException("serviceProvider"); |
- } |
- |
- if(existingEngine == null) |
- { |
- MSBuild.Engine buildEngine = MSBuild.Engine.GlobalEngine; |
- return buildEngine; |
- } |
- |
- return existingEngine; |
- } |
- |
- /// <summary> |
- /// Gets an instance of an EnumConverter for enums that have PropertyPageTypeConverter attribute |
- /// </summary> |
- /// <typeparam name="T">The type to search for the PropertyPageTypeConverter attribute.</typeparam> |
- /// <returns>An instance of an enum converter, or null if none found.</returns> |
- private static EnumConverter GetEnumConverter<T>() |
- where T : struct |
- { |
- object[] attributes = typeof(T).GetCustomAttributes(typeof(PropertyPageTypeConverterAttribute), true); |
- |
- // There should be only one PropertyPageTypeConverterAttribute defined on T |
- if(attributes != null && attributes.Length == 1) |
- { |
- |
- Debug.Assert(attributes[0] is PropertyPageTypeConverterAttribute, "The returned attribute must be an attribute is PropertyPageTypeConverterAttribute"); |
- PropertyPageTypeConverterAttribute converterAttribute = (PropertyPageTypeConverterAttribute)attributes[0]; |
- |
- if(converterAttribute.ConverterType.IsSubclassOf(typeof(EnumConverter))) |
- { |
- return Activator.CreateInstance(converterAttribute.ConverterType) as EnumConverter; |
- } |
- } |
- |
- return null; |
- } |
- |
- /// <summary>> |
- /// Checks if the file name is all the given character. |
- /// </summary> |
- private static bool IsFileNameAllGivenCharacter(char c, string fileName) |
- { |
- // A valid file name cannot be all "c" . |
- int charFound = 0; |
- for(charFound = 0; charFound < fileName.Length && fileName[charFound] == c; ++charFound) ; |
- if(charFound >= fileName.Length) |
- { |
- return true; |
- } |
- |
- return false; |
- } |
- |
- /// <summary> |
- /// Checks whether a file part contains valid characters. The file part can be any part of a non rooted path. |
- /// </summary> |
- /// <param name="filePart"></param> |
- /// <returns></returns> |
- private static bool IsFilePartInValid(string filePart) |
- { |
- if(String.IsNullOrEmpty(filePart)) |
- { |
- return true; |
- } |
- String reservedName = "(\\b(nul|con|aux|prn)\\b)|(\\b((com|lpt)[0-9])\\b)"; |
- String invalidChars = @"([/?:&\\*<>|#%" + '\"' + "])"; |
- String regexToUseForFileName = reservedName + "|" + invalidChars; |
- String fileNameToVerify = filePart; |
- |
- // Define a regular expression that covers all characters that are not in the safe character sets. |
- // It is compiled for performance. |
- |
- // The filePart might still be a file and extension. If it is like that then we must check them separately, since different rules apply |
- string extension = String.Empty; |
- try |
- { |
- extension = Path.GetExtension(filePart); |
- } |
- // We catch the ArgumentException because we want this method to return true if the filename is not valid. FilePart could be for example #¤&%"¤&"% and that would throw ArgumentException on GetExtension |
- catch(ArgumentException) |
- { |
- return true; |
- } |
- |
- if(!String.IsNullOrEmpty(extension)) |
- { |
- // Check the extension first |
- String regexToUseForExtension = invalidChars; |
- Regex unsafeCharactersRegex = new Regex(regexToUseForExtension, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); |
- bool isMatch = unsafeCharactersRegex.IsMatch(extension); |
- if(isMatch) |
- { |
- return isMatch; |
- } |
- |
- // We want to verify here everything but the extension. |
- // We cannot use GetFileNameWithoutExtension because it might be that for example (..\\filename.txt) is passed in asnd that should fail, since that is not a valid filename. |
- fileNameToVerify = filePart.Substring(0, filePart.Length - extension.Length); |
- |
- if(String.IsNullOrEmpty(fileNameToVerify)) |
- { |
- return true; |
- } |
- } |
- |
- // We verify CLOCK$ outside the regex since for some reason the regex is not matching the clock\\$ added. |
- if(String.Compare(fileNameToVerify, "CLOCK$", StringComparison.OrdinalIgnoreCase) == 0) |
- { |
- return true; |
- } |
- |
- Regex unsafeFileNameCharactersRegex = new Regex(regexToUseForFileName, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); |
- return unsafeFileNameCharactersRegex.IsMatch(fileNameToVerify); |
- } |
- |
- /// <summary> |
- /// Copy a directory recursively to the specified non-existing directory |
- /// </summary> |
- /// <param name="source">Directory to copy from</param> |
- /// <param name="target">Directory to copy to</param> |
- public static void RecursivelyCopyDirectory(string source, string target) |
- { |
- // Make sure it doesn't already exist |
- if(Directory.Exists(target)) |
- throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FileOrFolderAlreadyExists, CultureInfo.CurrentUICulture), target)); |
- |
- Directory.CreateDirectory(target); |
- DirectoryInfo directory = new DirectoryInfo(source); |
- |
- // Copy files |
- foreach(FileInfo file in directory.GetFiles()) |
- { |
- file.CopyTo(Path.Combine(target, file.Name)); |
- } |
- |
- // Now recurse to child directories |
- foreach(DirectoryInfo child in directory.GetDirectories()) |
- { |
- RecursivelyCopyDirectory(child.FullName, Path.Combine(target, child.Name)); |
- } |
- } |
- |
- /// <summary> |
- /// Canonicalizes a file name, including: |
- /// - determines the full path to the file |
- /// - casts to upper case |
- /// Canonicalizing a file name makes it possible to compare file names using simple simple string comparison. |
- /// |
- /// Note: this method does not handle shared drives and UNC drives. |
- /// </summary> |
- /// <param name="anyFileName">A file name, which can be relative/absolute and contain lower-case/upper-case characters.</param> |
- /// <returns>Canonicalized file name.</returns> |
- internal static string CanonicalizeFileName(string anyFileName) |
- { |
- // Get absolute path |
- // Note: this will not handle UNC paths |
- FileInfo fileInfo = new FileInfo(anyFileName); |
- string fullPath = fileInfo.FullName; |
- |
- // Cast to upper-case |
- fullPath = fullPath.ToUpper(CultureInfo.CurrentCulture); |
- |
- return fullPath; |
- } |
- |
- |
- /// <summary> |
- /// Determines if a file is a template. |
- /// </summary> |
- /// <param name="fileName">The file to check whether it is a template file</param> |
- /// <returns>true if the file is a template file</returns> |
- internal static bool IsTemplateFile(string fileName) |
- { |
- if(String.IsNullOrEmpty(fileName)) |
- { |
- return false; |
- } |
- |
- string extension = Path.GetExtension(fileName); |
- return (String.Compare(extension, ".vstemplate", StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(extension, ".vsz", StringComparison.OrdinalIgnoreCase) == 0); |
- } |
- |
- /// <summary> |
- /// Retrives the configuration and the platform using the IVsSolutionBuildManager2 interface. |
- /// </summary> |
- /// <param name="serviceProvider">A service provider.</param> |
- /// <param name="hierarchy">The hierrachy whose configuration is requested.</param> |
- /// <param name="configuration">The name of the active configuration.</param> |
- /// <param name="platform">The name of the platform.</param> |
- /// <returns>true if successfull.</returns> |
- internal static bool TryGetActiveConfigurationAndPlatform(System.IServiceProvider serviceProvider, IVsHierarchy hierarchy, out string configuration, out string platform) |
- { |
- if(serviceProvider == null) |
- { |
- throw new ArgumentNullException("serviceProvider"); |
- } |
- |
- if(hierarchy == null) |
- { |
- throw new ArgumentNullException("hierarchy"); |
- } |
- |
- configuration = String.Empty; |
- platform = String.Empty; |
- |
- IVsSolutionBuildManager2 solutionBuildManager = serviceProvider.GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager2; |
- |
- if(solutionBuildManager == null) |
- { |
- return false; |
- } |
- |
- IVsProjectCfg[] activeConfigs = new IVsProjectCfg[1]; |
- ErrorHandler.ThrowOnFailure(solutionBuildManager.FindActiveProjectCfg(IntPtr.Zero, IntPtr.Zero, hierarchy, activeConfigs)); |
- |
- IVsProjectCfg activeCfg = activeConfigs[0]; |
- |
- // Can it be that the activeCfg is null? |
- System.Diagnostics.Debug.Assert(activeCfg != null, "Cannot find the active configuration"); |
- |
- string canonicalName; |
- ErrorHandler.ThrowOnFailure(activeCfg.get_CanonicalName(out canonicalName)); |
- |
- return ProjectConfig.TrySplitConfigurationCanonicalName(canonicalName, out configuration, out platform); |
- } |
- |
- /// <summary> |
- /// Determines whether the shell is in command line mode. |
- /// </summary> |
- /// <param name="serviceProvider">A reference to a Service Provider.</param> |
- /// <returns>true if the shell is in command line mode. false otherwise.</returns> |
- internal static bool IsShellInCommandLineMode(System.IServiceProvider serviceProvider) |
- { |
- if(serviceProvider == null) |
- { |
- throw new ArgumentNullException("serviceProvider"); |
- } |
- |
- IVsShell shell = serviceProvider.GetService(typeof(SVsShell)) as IVsShell; |
- if(shell == null) |
- { |
- throw new InvalidOperationException(); |
- } |
- |
- object isInCommandLineModeAsObject; |
- ErrorHandler.ThrowOnFailure(shell.GetProperty((int)__VSSPROPID.VSSPROPID_IsInCommandLineMode, out isInCommandLineModeAsObject)); |
- |
- return ((bool)isInCommandLineModeAsObject); |
- } |
- |
- /// <summary> |
- /// Saves the dialog state in the solution |
- /// </summary> |
- /// <param name="serviceProvider">A reference to a Service Provider.</param> |
- /// <param name="projectLoadSecurityDialogState">The dialog state</param> |
- internal static void SaveDialogStateInSolution(IServiceProvider serviceProvider, _ProjectLoadSecurityDialogState projectLoadSecurityDialogState) |
- { |
- if(serviceProvider == null) |
- { |
- throw new ArgumentNullException("serviceProvider"); |
- } |
- |
- IVsSolution solution = serviceProvider.GetService(typeof(SVsSolution)) as IVsSolution; |
- |
- if(solution == null) |
- { |
- throw new InvalidOperationException(); |
- } |
- |
- ErrorHandler.ThrowOnFailure(solution.SetProperty((int)__VSPROPID2.VSPROPID_ProjectLoadSecurityDialogState, projectLoadSecurityDialogState)); |
- } |
- |
- /// <summary> |
- /// Checks if the project location is secure. |
- /// </summary> |
- /// <param name="location">The project folder.</param> |
- /// <returns>True if the project location is secure.</returns> |
- internal static bool IsProjectLocationSecure(string location) |
- { |
- if(String.IsNullOrEmpty(location) || location.Length > NativeMethods.MAX_PATH) |
- { |
- return false; |
- } |
- |
- Zone zone = Zone.CreateFromUrl(location); |
- if(zone == null) |
- { |
- return false; |
- } |
- |
- // Now use the utilities from the msbuild api to check us the path. |
- Microsoft.VisualStudio.Build.ComInteropWrapper.Utilities utilities = new Microsoft.VisualStudio.Build.ComInteropWrapper.Utilities(); |
- |
- return utilities.CheckPath(location, (int)zone.SecurityZone); |
- } |
- } |
-} |