Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: obsolete/Microsoft.VisualStudio.Project/Utilities.cs

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /// Copyright (c) Microsoft Corporation. All rights reserved.
2
3 using System;
4 using System.Collections.Generic;
5 using System.ComponentModel;
6 using System.Diagnostics;
7 using System.Diagnostics.CodeAnalysis;
8 using System.Drawing;
9 using System.Globalization;
10 using System.IO;
11 using System.Runtime.InteropServices;
12 using System.Security.Permissions;
13 using System.Security.Policy;
14 using System.Text;
15 using System.Text.RegularExpressions;
16 using System.Windows.Forms;
17 using Microsoft.VisualStudio;
18 using Microsoft.VisualStudio.OLE.Interop;
19 using Microsoft.VisualStudio.Shell;
20 using Microsoft.VisualStudio.Shell.Interop;
21 using Microsoft.Win32;
22 using IServiceProvider = System.IServiceProvider;
23 using MSBuild = Microsoft.Build.BuildEngine;
24 using VSRegistry = Microsoft.VisualStudio.Shell.VSRegistry;
25
26 namespace Microsoft.VisualStudio.Project
27 {
28 public static class Utilities
29 {
30 private const string defaultMSBuildVersion = "2.0";
31
32 /// <summary>
33 /// Look in the registry under the current hive for the path
34 /// of MSBuild
35 /// </summary>
36 /// <returns></returns>
37 [CLSCompliant(false)]
38 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBe CasedCorrectly", MessageId = "Ms")]
39 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBe SpelledCorrectly", MessageId = "msbuild")]
40 public static string GetMsBuildPath(IServiceProvider serviceProv ider)
41 {
42 return GetMsBuildPath(serviceProvider, defaultMSBuildVer sion);
43 }
44
45 /// <summary>
46 /// Search the registry for the tools path for MSBuild.
47 /// </summary>
48 /// <param name="serviceProvider">The service provider.</param>
49 /// <param name="version">Msbuild version.</param>
50 /// <returns>The msbuild tools path</returns>
51 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBe CasedCorrectly", MessageId = "Ms")]
52 public static string GetMsBuildPath(IServiceProvider serviceProv ider, string version)
53 {
54 string msBuildPath = null;
55 using(RegistryKey root = VSRegistry.RegistryRoot(service Provider, __VsLocalRegistryType.RegType_Configuration, false))
56 {
57 // Get the value from the registry
58 using(RegistryKey vsKey = root.OpenSubKey("MSBui ld", false))
59 {
60 msBuildPath = (string)vsKey.GetValue("MS BuildBinPath", null);
61 }
62 }
63 if(!string.IsNullOrEmpty(msBuildPath))
64 {
65 return msBuildPath;
66 }
67
68 // The path to MSBuild was not found in the VisualStudio 's registry hive, so try to
69 // find it in the new MSBuild hive.
70 string registryPath = string.Format(CultureInfo.Invarian tCulture, "Software\\Microsoft\\MSBuild\\ToolsVersions\\{0}", version);
71 using(Microsoft.Win32.RegistryKey msbuildKey = Microsoft .Win32.Registry.LocalMachine.OpenSubKey(registryPath, false))
72 {
73 msBuildPath = (string)msbuildKey.GetValue("MSBui ldToolsPath", null);
74 }
75 if(string.IsNullOrEmpty(msBuildPath))
76 {
77 string error = SR.GetString(SR.ErrorMsBuildRegis tration, CultureInfo.CurrentUICulture);
78 throw new FileLoadException(error);
79 }
80 return msBuildPath;
81 }
82
83 /// <summary>
84 /// Is Visual Studio in design mode.
85 /// </summary>
86 /// <param name="serviceProvider">The service provider.</param>
87 /// <returns>true if visual studio is in design mode</returns>
88 public static bool IsVisualStudioInDesignMode(IServiceProvider s ite)
89 {
90 IVsMonitorSelection selectionMonitor = site.GetService(t ypeof(IVsMonitorSelection)) as IVsMonitorSelection;
91 uint cookie = 0;
92 int active = 0;
93 Guid designContext = VSConstants.UICONTEXT_DesignMode;
94 ErrorHandler.ThrowOnFailure(selectionMonitor.GetCmdUICon textCookie(ref designContext, out cookie));
95 ErrorHandler.ThrowOnFailure(selectionMonitor.IsCmdUICont extActive(cookie, out active));
96 return active != 0;
97 }
98
99 /// <include file='doc\VsShellUtilities.uex' path='docs/doc[@for ="Utilities.IsInAutomationFunction"]/*' />
100 /// <devdoc>
101 /// Is an extensibility object executing an automation function.
102 /// </devdoc>
103 /// <param name="serviceProvider">The service provider.</param>
104 /// <returns>true if the extensiblity object is executing an aut omation function.</returns>
105 public static bool IsInAutomationFunction(IServiceProvider servi ceProvider)
106 {
107 if(serviceProvider == null)
108 {
109 throw new ArgumentNullException("serviceProvider ");
110 }
111
112 IVsExtensibility3 extensibility = serviceProvider.GetSer vice(typeof(EnvDTE.IVsExtensibility)) as IVsExtensibility3;
113
114 if(extensibility == null)
115 {
116 throw new InvalidOperationException();
117 }
118 int inAutomation = 0;
119 ErrorHandler.ThrowOnFailure(extensibility.IsInAutomation Function(out inAutomation));
120 return inAutomation != 0;
121 }
122
123 /// <summary>
124 /// Creates a semicolon delinited list of strings. This can be u sed to provide the properties for VSHPROPID_CfgPropertyPagesCLSIDList, VSHPROPID _PropertyPagesCLSIDList, VSHPROPID_PriorityPropertyPagesCLSIDList
125 /// </summary>
126 /// <param name="guids">An array of Guids.</param>
127 /// <returns>A semicolon delimited string, or null</returns>
128 [CLSCompliant(false)]
129 public static string CreateSemicolonDelimitedListOfStringFromGui ds(Guid[] guids)
130 {
131 if(guids == null || guids.Length == 0)
132 {
133 return null;
134 }
135
136 // Create a StringBuilder with a pre-allocated buffer bi g enough for the
137 // final string. 39 is the length of a GUID in the "B" f orm plus the final ';'
138 StringBuilder stringList = new StringBuilder(39 * guids. Length);
139 for(int i = 0; i < guids.Length; i++)
140 {
141 stringList.Append(guids[i].ToString("B"));
142 stringList.Append(";");
143 }
144
145 return stringList.ToString().TrimEnd(';');
146 }
147
148 private static char[] curlyBraces = new char[] { '{', '}' };
149 /// <summary>
150 /// Take list of guids as a single string and generate an array of Guids from it
151 /// </summary>
152 /// <param name="guidList">Semi-colon separated list of Guids</p aram>
153 /// <returns>Array of Guids</returns>
154 [CLSCompliant(false)]
155 public static Guid[] GuidsArrayFromSemicolonDelimitedStringOfGui ds(string guidList)
156 {
157 if(guidList == null)
158 {
159 return null;
160 }
161
162 List<Guid> guids = new List<Guid>();
163 string[] guidsStrings = guidList.Split(';');
164 foreach(string guid in guidsStrings)
165 {
166 if(!String.IsNullOrEmpty(guid))
167 guids.Add(new Guid(guid.Trim(curlyBraces )));
168 }
169
170 return guids.ToArray();
171 }
172
173 /// <summary>
174 /// Validates a file path by validating all file parts. If the
175 /// the file name is invalid it throws an exception if the proje ct is in automation. Otherwise it shows a dialog box with the error message.
176 /// </summary>
177 /// <param name="serviceProvider">The service provider</param>
178 /// <param name="filePath">A full path to a file name</param>
179 /// <exception cref="InvalidOperationException">In case of failu re an InvalidOperationException is thrown.</exception>
180 public static void ValidateFileName(IServiceProvider serviceProv ider, string filePath)
181 {
182 string errorMessage = String.Empty;
183 if(String.IsNullOrEmpty(filePath))
184 {
185 errorMessage = SR.GetString(SR.ErrorInvalidFileN ame, CultureInfo.CurrentUICulture);
186 }
187 else if(filePath.Length > NativeMethods.MAX_PATH)
188 {
189 errorMessage = String.Format(CultureInfo.Current Culture, SR.GetString(SR.PathTooLong, CultureInfo.CurrentUICulture), filePath);
190 }
191 else if(ContainsInvalidFileNameChars(filePath))
192 {
193 errorMessage = SR.GetString(SR.ErrorInvalidFileN ame, CultureInfo.CurrentUICulture);
194 }
195
196 if(errorMessage.Length == 0)
197 {
198 string fileName = Path.GetFileName(filePath);
199 if(String.IsNullOrEmpty(fileName) || IsFileNameI nvalid(fileName))
200 {
201 errorMessage = SR.GetString(SR.ErrorInva lidFileName, CultureInfo.CurrentUICulture);
202 }
203 else
204 {
205 string fileNameWithoutExtension = Path.G etFileNameWithoutExtension(fileName);
206
207 // If there is no filename or it starts with a leading dot issue an error message and quit.
208 if(String.IsNullOrEmpty(fileNameWithoutE xtension) || fileNameWithoutExtension[0] == '.')
209 {
210 errorMessage = SR.GetString(SR.F ileNameCannotContainALeadingPeriod, CultureInfo.CurrentUICulture);
211 }
212 }
213 }
214
215 if(errorMessage.Length > 0)
216 {
217 // If it is not called from an automation method show a dialog box.
218 if(!Utilities.IsInAutomationFunction(serviceProv ider))
219 {
220 string title = null;
221 OLEMSGICON icon = OLEMSGICON.OLEMSGICON_ CRITICAL;
222 OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEM SGBUTTON_OK;
223 OLEMSGDEFBUTTON defaultButton = OLEMSGDE FBUTTON.OLEMSGDEFBUTTON_FIRST;
224 VsShellUtilities.ShowMessageBox(serviceP rovider, title, errorMessage, icon, buttons, defaultButton);
225 }
226 else
227 {
228 throw new InvalidOperationException(erro rMessage);
229 }
230 }
231
232 }
233
234 /// <summary>
235 /// Creates a CALPOLESTR from a list of strings
236 /// It is the responsability of the caller to release this memor y.
237 /// </summary>
238 /// <param name="guids"></param>
239 /// <returns>A CALPOLESTR that was created from the the list of strings.</returns>
240 [CLSCompliant(false)]
241 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBe CasedCorrectly", MessageId = "CALPOLESTR")]
242 public static CALPOLESTR CreateCALPOLESTR(IList<string> strings)
243 {
244 CALPOLESTR calpolStr = new CALPOLESTR();
245
246 if(strings != null)
247 {
248 // Demand unmanaged permissions in order to acce ss unmanaged memory.
249 new SecurityPermission(SecurityPermissionFlag.Un managedCode).Demand();
250
251 calpolStr.cElems = (uint)strings.Count;
252
253 int size = Marshal.SizeOf(typeof(IntPtr));
254
255 calpolStr.pElems = Marshal.AllocCoTaskMem(string s.Count * size);
256
257 IntPtr ptr = calpolStr.pElems;
258
259 foreach(string aString in strings)
260 {
261 IntPtr tempPtr = Marshal.StringToCoTaskM emUni(aString);
262 Marshal.WriteIntPtr(ptr, tempPtr);
263 ptr = new IntPtr(ptr.ToInt64() + size);
264 }
265 }
266
267 return calpolStr;
268 }
269
270 /// <summary>
271 /// Creates a CADWORD from a list of tagVsSccFilesFlags. Memory is allocated for the elems.
272 /// It is the responsability of the caller to release this memor y.
273 /// </summary>
274 /// <param name="guids"></param>
275 /// <returns>A CADWORD created from the list of tagVsSccFilesFla gs.</returns>
276 [CLSCompliant(false)]
277 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBe CasedCorrectly", MessageId = "CADWORD")]
278 public static CADWORD CreateCADWORD(IList<tagVsSccFilesFlags> fl ags)
279 {
280 CADWORD cadWord = new CADWORD();
281
282 if(flags != null)
283 {
284 // Demand unmanaged permissions in order to acce ss unmanaged memory.
285 new SecurityPermission(SecurityPermissionFlag.Un managedCode).Demand();
286
287 cadWord.cElems = (uint)flags.Count;
288
289 int size = Marshal.SizeOf(typeof(UInt32));
290
291 cadWord.pElems = Marshal.AllocCoTaskMem(flags.Co unt * size);
292
293 IntPtr ptr = cadWord.pElems;
294
295 foreach(tagVsSccFilesFlags flag in flags)
296 {
297 Marshal.WriteInt32(ptr, (int)flag);
298 ptr = new IntPtr(ptr.ToInt64() + size);
299 }
300 }
301
302 return cadWord;
303 }
304
305 /// <summary>
306 /// Splits a bitmap from a Stream into an ImageList
307 /// </summary>
308 /// <param name="imageStream">A Stream representing a Bitmap</pa ram>
309 /// <returns>An ImageList object representing the images from th e given stream</returns>
310 public static ImageList GetImageList(Stream imageStream)
311 {
312 ImageList ilist = new ImageList();
313
314 if(imageStream == null)
315 {
316 return ilist;
317 }
318 ilist.ColorDepth = ColorDepth.Depth24Bit;
319 ilist.ImageSize = new Size(16, 16);
320 Bitmap bitmap = new Bitmap(imageStream);
321 ilist.Images.AddStrip(bitmap);
322 ilist.TransparentColor = Color.Magenta;
323 return ilist;
324 }
325
326 /// <summary>
327 /// Splits a bitmap from a pointer to an ImageList
328 /// </summary>
329 /// <param name="imageListAsPointer">A pointer to a bitmap of im ages to split</param>
330 /// <returns>An ImageList object representing the images from th e given stream</returns>
331 public static ImageList GetImageList(object imageListAsPointer)
332 {
333 ImageList images = null;
334
335 IntPtr intPtr = new IntPtr((int)imageListAsPointer);
336 HandleRef hImageList = new HandleRef(null, intPtr);
337 int count = UnsafeNativeMethods.ImageList_GetImageCount( hImageList);
338
339 if(count > 0)
340 {
341 // Create a bitmap big enough to hold all the im ages
342 Bitmap b = new Bitmap(16 * count, 16);
343 Graphics g = Graphics.FromImage(b);
344
345 // Loop through and extract each image from the imagelist into our own bitmap
346 IntPtr hDC = IntPtr.Zero;
347 try
348 {
349 hDC = g.GetHdc();
350 HandleRef handleRefDC = new HandleRef(nu ll, hDC);
351 for(int i = 0; i < count; i++)
352 {
353 UnsafeNativeMethods.ImageList_Dr aw(hImageList, i, handleRefDC, i * 16, 0, NativeMethods.ILD_NORMAL);
354 }
355 }
356 finally
357 {
358 if(g != null && hDC != IntPtr.Zero)
359 {
360 g.ReleaseHdc(hDC);
361 }
362 }
363
364 // Create a new imagelist based on our stolen im ages
365 images = new ImageList();
366 images.ColorDepth = ColorDepth.Depth24Bit;
367 images.ImageSize = new Size(16, 16);
368 images.Images.AddStrip(b);
369 }
370 return images;
371 }
372
373 /// <summary>
374 /// Gets the active configuration name.
375 /// </summary>
376 /// <param name="automationObject">The automation object.</param >
377 /// <returns>The name of the active configuartion.</returns>
378 internal static string GetActiveConfigurationName(EnvDTE.Project automationObject)
379 {
380 if(automationObject == null)
381 {
382 throw new ArgumentNullException("automationObjec t");
383 }
384
385 string currentConfigName = string.Empty;
386 if(automationObject.ConfigurationManager != null)
387 {
388 EnvDTE.Configuration activeConfig = automationOb ject.ConfigurationManager.ActiveConfiguration;
389 if(activeConfig != null)
390 {
391 currentConfigName = activeConfig.Configu rationName;
392 }
393 }
394 return currentConfigName;
395
396 }
397
398
399 /// <summary>
400 /// Verifies that two objects represent the same instance of a C OM object.
401 /// This essentially compares the IUnkown pointers of the 2 obje cts.
402 /// This is needed in scenario where aggregation is involved.
403 /// </summary>
404 /// <param name="obj1">Can be an object, interface or IntPtr</pa ram>
405 /// <param name="obj2">Can be an object, interface or IntPtr</pa ram>
406 /// <returns>True if the 2 items represent the same thing</retur ns>
407 [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNo tContainTypeNames", MessageId = "obj")]
408 public static bool IsSameComObject(object obj1, object obj2)
409 {
410 bool isSame = false;
411 IntPtr unknown1 = IntPtr.Zero;
412 IntPtr unknown2 = IntPtr.Zero;
413 try
414 {
415 // If we have 2 null, then they are not COM obje cts and as such "it's not the same COM object"
416 if(obj1 != null && obj2 != null)
417 {
418 unknown1 = QueryInterfaceIUnknown(obj1);
419 unknown2 = QueryInterfaceIUnknown(obj2);
420
421 isSame = IntPtr.Equals(unknown1, unknown 2);
422 }
423 }
424 finally
425 {
426 if(unknown1 != IntPtr.Zero)
427 {
428 Marshal.Release(unknown1);
429 }
430
431 if(unknown2 != IntPtr.Zero)
432 {
433 Marshal.Release(unknown2);
434 }
435
436 }
437
438 return isSame;
439 }
440
441 /// <summary>
442 /// Retrieve the IUnknown for the managed or COM object passed i n.
443 /// </summary>
444 /// <param name="objToQuery">Managed or COM object.</param>
445 /// <returns>Pointer to the IUnknown interface of the object.</r eturns>
446 internal static IntPtr QueryInterfaceIUnknown(object objToQuery)
447 {
448 bool releaseIt = false;
449 IntPtr unknown = IntPtr.Zero;
450 IntPtr result;
451 try
452 {
453 if(objToQuery is IntPtr)
454 {
455 unknown = (IntPtr)objToQuery;
456 }
457 else
458 {
459 // This is a managed object (or RCW)
460 unknown = Marshal.GetIUnknownForObject(o bjToQuery);
461 releaseIt = true;
462 }
463
464 // We might already have an IUnknown, but if thi s is an aggregated
465 // object, it may not be THE IUnknown until we Q I for it.
466 Guid IID_IUnknown = VSConstants.IID_IUnknown;
467 ErrorHandler.ThrowOnFailure(Marshal.QueryInterfa ce(unknown, ref IID_IUnknown, out result));
468 }
469 finally
470 {
471 if(releaseIt && unknown != IntPtr.Zero)
472 {
473 Marshal.Release(unknown);
474 }
475
476 }
477
478 return result;
479 }
480
481 /// <summary>
482 /// Returns true if thename that can represent a path, absolut o r relative, or a file name contains invalid filename characters.
483 /// </summary>
484 /// <param name="name">File name</param>
485 /// <returns>true if file name is invalid</returns>
486 public static bool ContainsInvalidFileNameChars(string name)
487 {
488 if(String.IsNullOrEmpty(name))
489 {
490 return true;
491 }
492
493 try
494 {
495 if(Path.IsPathRooted(name) && !name.StartsWith(@ "\\", StringComparison.Ordinal))
496 {
497 string root = Path.GetPathRoot(name);
498 name = name.Substring(root.Length);
499 }
500 }
501 // The Path methods used by ContainsInvalidFileNameChars return argument exception if the filePath contains invalid characters.
502 catch(ArgumentException)
503 {
504 return true;
505 }
506
507 Microsoft.VisualStudio.Shell.Url uri = new Microsoft.Vis ualStudio.Shell.Url(name);
508
509 // This might be confusing bur Url.IsFile means that the uri represented by the name is either absolut or relative.
510 if(uri.IsFile)
511 {
512 string[] segments = uri.Segments;
513 if(segments != null && segments.Length > 0)
514 {
515 foreach(string segment in segments)
516 {
517 if(IsFilePartInValid(segment))
518 {
519 return true;
520 }
521 }
522
523 // Now the last segment should be specia lly taken care, since that cannot be all dots or spaces.
524 string lastSegment = segments[segments.L ength - 1];
525 string filePart = Path.GetFileNameWithou tExtension(lastSegment);
526 if(IsFileNameAllGivenCharacter('.', file Part) || IsFileNameAllGivenCharacter(' ', filePart))
527 {
528 return true;
529 }
530 }
531 }
532 else
533 {
534 // The assumption here is that we got a file nam e.
535 string filePart = Path.GetFileNameWithoutExtensi on(name);
536 if(IsFileNameAllGivenCharacter('.', filePart) || IsFileNameAllGivenCharacter(' ', filePart))
537 {
538 return true;
539 }
540
541
542 return IsFilePartInValid(name);
543 }
544
545 return false;
546 }
547
548 /// Cehcks if a file name is valid.
549 /// </devdoc>
550 /// <param name="fileName">The name of the file</param>
551 /// <returns>True if the file is valid.</returns>
552 public static bool IsFileNameInvalid(string fileName)
553 {
554 if(String.IsNullOrEmpty(fileName))
555 {
556 return true;
557 }
558
559 if(IsFileNameAllGivenCharacter('.', fileName) || IsFileN ameAllGivenCharacter(' ', fileName))
560 {
561 return true;
562 }
563
564
565 return IsFilePartInValid(fileName);
566
567 }
568
569 /// <summary>
570 /// Helper method to call a converter explicitely to convert to an enum type
571 /// </summary>
572 /// <typeparam name="T">THe enum to convert to</typeparam>
573 /// <typeparam name="V">The converter that will be created</type param>
574 /// <param name="value">The enum value to be converted to</param >
575 /// <param name="typeToConvert">The type to convert</param>
576 /// <param name="culture">The culture to use to read the localiz ed strings</param>
577 /// <returns></returns>
578 [CLSCompliant(false)]
579 public static object ConvertToType<T>(T value, Type typeToConver t, CultureInfo culture)
580 where T : struct
581 {
582 EnumConverter converter = GetEnumConverter<T>();
583 if(converter == null)
584 {
585 return null;
586 }
587 if(converter.CanConvertTo(typeToConvert))
588 {
589 return converter.ConvertTo(null, culture, value, typeToConvert);
590 }
591
592 return null;
593 }
594
595 /// <summary>
596 /// Helper method for converting from a string to an enum using a converter.
597 /// </summary>
598 /// <typeparam name="T"></typeparam>
599 /// <param name="value"></param>
600 /// <param name="culture">The culture to use to read the localiz ed strings</param>
601 /// <returns></returns>
602 [CLSCompliant(false)]
603 public static Nullable<T> ConvertFromType<T>(string value, Cultu reInfo culture)
604 where T : struct
605 {
606 Nullable<T> returnValue = new Nullable<T>();
607
608 returnValue = returnValue.GetValueOrDefault();
609
610 if(value == null)
611 {
612 return returnValue;
613 }
614
615 EnumConverter converter = GetEnumConverter<T>();
616 if(converter == null)
617 {
618 return returnValue;
619 }
620
621 if(converter.CanConvertFrom(value.GetType()))
622 {
623 object converted = converter.ConvertFrom(null, c ulture, value);
624
625 if(converted != null && (converted is T))
626 {
627 returnValue = (T)converted;
628 }
629 }
630
631 return returnValue;
632 }
633
634
635 /// <summary>
636 /// Sets a string value from an enum
637 /// </summary>
638 /// <typeparam name="T">The enum type</typeparam>
639 /// <param name="enumValue">The value of teh enum.</param>
640 /// <returns></returns>
641 [CLSCompliant(false)]
642 public static string SetStringValueFromConvertedEnum<T>(T enumVa lue, CultureInfo culture)
643 where T : struct
644 {
645 string convertToType = ConvertToType<T>(enumValue, typeo f(string), culture) as string;
646
647 if(convertToType == null)
648 {
649 return String.Empty;
650 }
651
652 return convertToType;
653 }
654
655
656 /// <summary>
657 /// Initializes the in memory project. Sets BuildEnabled on the project to true.
658 /// </summary>
659 /// <param name="engine">The build engine to use to create a bui ld project.</param>
660 /// <param name="fullProjectPath">The full path of the project.< /param>
661 /// <returns>A loaded msbuild project.</returns>
662 internal static MSBuild.Project InitializeMsBuildProject(MSBuild .Engine buildEngine, string fullProjectPath)
663 {
664 if(buildEngine == null)
665 {
666 throw new ArgumentNullException("buildEngine");
667 }
668
669 if(String.IsNullOrEmpty(fullProjectPath))
670 {
671 throw new ArgumentException(SR.GetString(SR.Inva lidParameter, CultureInfo.CurrentUICulture), "fullProjectPath");
672 }
673
674 // Check if the project already has been loaded with the fullProjectPath. If yes return the build project associated to it.
675 MSBuild.Project buildProject = buildEngine.GetLoadedProj ect(fullProjectPath);
676
677 if(buildProject == null)
678 {
679 buildProject = buildEngine.CreateNewProject();
680 buildProject.BuildEnabled = true;
681 buildProject.Load(fullProjectPath);
682 }
683
684 return buildProject;
685 }
686
687 /// <summary>
688 /// Loads a project file for the file. If the build project exis ts and it was loaded with a different file then it is unloaded first.
689 /// </summary>
690 /// <param name="engine">The build engine to use to create a bui ld project.</param>
691 /// <param name="fullProjectPath">The full path of the project.< /param>
692 /// <param name="exitingBuildProject">An Existing build project that will be reloaded.</param>
693 /// <returns>A loaded msbuild project.</returns>
694 internal static MSBuild.Project ReinitializeMsBuildProject(MSBui ld.Engine buildEngine, string fullProjectPath, MSBuild.Project exitingBuildProje ct)
695 {
696 // If we have a build project that has been loaded with another file unload it.
697 try
698 {
699 if(exitingBuildProject != null && exitingBuildPr oject.ParentEngine != null && !NativeMethods.IsSamePath(exitingBuildProject.Full FileName, fullProjectPath))
700 {
701 exitingBuildProject.ParentEngine.UnloadP roject(exitingBuildProject);
702 }
703 }
704 // We catch Invalid operation exception because if the project was unloaded while we touch the ParentEngine the msbuild API throws.
705 // Is there a way to figure out that a project was unloa ded?
706 catch(InvalidOperationException)
707 {
708 }
709
710 return Utilities.InitializeMsBuildProject(buildEngine, f ullProjectPath);
711 }
712
713 /// <summary>
714 /// 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 h ave its bin path set.
715 /// </summary>
716 /// <param name="engine">An instance of MSBuild.Engine build eng ine, that will be checked if initialized.</param>
717 /// <param name="engine">The service provider.</param>
718 /// <returns>The buildengine to use.</returns>
719 internal static MSBuild.Engine InitializeMsBuildEngine(MSBuild.E ngine existingEngine, IServiceProvider serviceProvider)
720 {
721 if(serviceProvider == null)
722 {
723 throw new ArgumentNullException("serviceProvider ");
724 }
725
726 if(existingEngine == null)
727 {
728 MSBuild.Engine buildEngine = MSBuild.Engine.Glob alEngine;
729 return buildEngine;
730 }
731
732 return existingEngine;
733 }
734
735 /// <summary>
736 /// Gets an instance of an EnumConverter for enums that have Pro pertyPageTypeConverter attribute
737 /// </summary>
738 /// <typeparam name="T">The type to search for the PropertyPageT ypeConverter attribute.</typeparam>
739 /// <returns>An instance of an enum converter, or null if none f ound.</returns>
740 private static EnumConverter GetEnumConverter<T>()
741 where T : struct
742 {
743 object[] attributes = typeof(T).GetCustomAttributes(type of(PropertyPageTypeConverterAttribute), true);
744
745 // There should be only one PropertyPageTypeConverterAtt ribute defined on T
746 if(attributes != null && attributes.Length == 1)
747 {
748
749 Debug.Assert(attributes[0] is PropertyPageTypeCo nverterAttribute, "The returned attribute must be an attribute is PropertyPageTy peConverterAttribute");
750 PropertyPageTypeConverterAttribute converterAttr ibute = (PropertyPageTypeConverterAttribute)attributes[0];
751
752 if(converterAttribute.ConverterType.IsSubclassOf (typeof(EnumConverter)))
753 {
754 return Activator.CreateInstance(converte rAttribute.ConverterType) as EnumConverter;
755 }
756 }
757
758 return null;
759 }
760
761 /// <summary>>
762 /// Checks if the file name is all the given character.
763 /// </summary>
764 private static bool IsFileNameAllGivenCharacter(char c, string f ileName)
765 {
766 // A valid file name cannot be all "c" .
767 int charFound = 0;
768 for(charFound = 0; charFound < fileName.Length && fileNa me[charFound] == c; ++charFound) ;
769 if(charFound >= fileName.Length)
770 {
771 return true;
772 }
773
774 return false;
775 }
776
777 /// <summary>
778 /// Checks whether a file part contains valid characters. The fi le part can be any part of a non rooted path.
779 /// </summary>
780 /// <param name="filePart"></param>
781 /// <returns></returns>
782 private static bool IsFilePartInValid(string filePart)
783 {
784 if(String.IsNullOrEmpty(filePart))
785 {
786 return true;
787 }
788 String reservedName = "(\\b(nul|con|aux|prn)\\b)|(\\b((c om|lpt)[0-9])\\b)";
789 String invalidChars = @"([/?:&\\*<>|#%" + '\"' + "])";
790 String regexToUseForFileName = reservedName + "|" + inva lidChars;
791 String fileNameToVerify = filePart;
792
793 // Define a regular expression that covers all character s that are not in the safe character sets.
794 // It is compiled for performance.
795
796 // The filePart might still be a file and extension. If it is like that then we must check them separately, since different rules apply
797 string extension = String.Empty;
798 try
799 {
800 extension = Path.GetExtension(filePart);
801 }
802 // We catch the ArgumentException because we want this m ethod to return true if the filename is not valid. FilePart could be for example #¤&%"¤&"% and that would throw ArgumentException on GetExtension
803 catch(ArgumentException)
804 {
805 return true;
806 }
807
808 if(!String.IsNullOrEmpty(extension))
809 {
810 // Check the extension first
811 String regexToUseForExtension = invalidChars;
812 Regex unsafeCharactersRegex = new Regex(regexToU seForExtension, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.C ultureInvariant);
813 bool isMatch = unsafeCharactersRegex.IsMatch(ext ension);
814 if(isMatch)
815 {
816 return isMatch;
817 }
818
819 // We want to verify here everything but the ext ension.
820 // We cannot use GetFileNameWithoutExtension bec ause it might be that for example (..\\filename.txt) is passed in asnd that shou ld fail, since that is not a valid filename.
821 fileNameToVerify = filePart.Substring(0, filePar t.Length - extension.Length);
822
823 if(String.IsNullOrEmpty(fileNameToVerify))
824 {
825 return true;
826 }
827 }
828
829 // We verify CLOCK$ outside the regex since for some rea son the regex is not matching the clock\\$ added.
830 if(String.Compare(fileNameToVerify, "CLOCK$", StringComp arison.OrdinalIgnoreCase) == 0)
831 {
832 return true;
833 }
834
835 Regex unsafeFileNameCharactersRegex = new Regex(regexToU seForFileName, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Cu ltureInvariant);
836 return unsafeFileNameCharactersRegex.IsMatch(fileNameToV erify);
837 }
838
839 /// <summary>
840 /// Copy a directory recursively to the specified non-existing d irectory
841 /// </summary>
842 /// <param name="source">Directory to copy from</param>
843 /// <param name="target">Directory to copy to</param>
844 public static void RecursivelyCopyDirectory(string source, strin g target)
845 {
846 // Make sure it doesn't already exist
847 if(Directory.Exists(target))
848 throw new ArgumentException(String.Format(Cultur eInfo.CurrentCulture, SR.GetString(SR.FileOrFolderAlreadyExists, CultureInfo.Cur rentUICulture), target));
849
850 Directory.CreateDirectory(target);
851 DirectoryInfo directory = new DirectoryInfo(source);
852
853 // Copy files
854 foreach(FileInfo file in directory.GetFiles())
855 {
856 file.CopyTo(Path.Combine(target, file.Name));
857 }
858
859 // Now recurse to child directories
860 foreach(DirectoryInfo child in directory.GetDirectories( ))
861 {
862 RecursivelyCopyDirectory(child.FullName, Path.Co mbine(target, child.Name));
863 }
864 }
865
866 /// <summary>
867 /// Canonicalizes a file name, including:
868 /// - determines the full path to the file
869 /// - casts to upper case
870 /// Canonicalizing a file name makes it possible to compare file names using simple simple string comparison.
871 ///
872 /// Note: this method does not handle shared drives and UNC driv es.
873 /// </summary>
874 /// <param name="anyFileName">A file name, which can be relative /absolute and contain lower-case/upper-case characters.</param>
875 /// <returns>Canonicalized file name.</returns>
876 internal static string CanonicalizeFileName(string anyFileName)
877 {
878 // Get absolute path
879 // Note: this will not handle UNC paths
880 FileInfo fileInfo = new FileInfo(anyFileName);
881 string fullPath = fileInfo.FullName;
882
883 // Cast to upper-case
884 fullPath = fullPath.ToUpper(CultureInfo.CurrentCulture);
885
886 return fullPath;
887 }
888
889
890 /// <summary>
891 /// Determines if a file is a template.
892 /// </summary>
893 /// <param name="fileName">The file to check whether it is a tem plate file</param>
894 /// <returns>true if the file is a template file</returns>
895 internal static bool IsTemplateFile(string fileName)
896 {
897 if(String.IsNullOrEmpty(fileName))
898 {
899 return false;
900 }
901
902 string extension = Path.GetExtension(fileName);
903 return (String.Compare(extension, ".vstemplate", StringC omparison.OrdinalIgnoreCase) == 0 || string.Compare(extension, ".vsz", StringCom parison.OrdinalIgnoreCase) == 0);
904 }
905
906 /// <summary>
907 /// Retrives the configuration and the platform using the IVsSol utionBuildManager2 interface.
908 /// </summary>
909 /// <param name="serviceProvider">A service provider.</param>
910 /// <param name="hierarchy">The hierrachy whose configuration is requested.</param>
911 /// <param name="configuration">The name of the active configura tion.</param>
912 /// <param name="platform">The name of the platform.</param>
913 /// <returns>true if successfull.</returns>
914 internal static bool TryGetActiveConfigurationAndPlatform(System .IServiceProvider serviceProvider, IVsHierarchy hierarchy, out string configurat ion, out string platform)
915 {
916 if(serviceProvider == null)
917 {
918 throw new ArgumentNullException("serviceProvider ");
919 }
920
921 if(hierarchy == null)
922 {
923 throw new ArgumentNullException("hierarchy");
924 }
925
926 configuration = String.Empty;
927 platform = String.Empty;
928
929 IVsSolutionBuildManager2 solutionBuildManager = serviceP rovider.GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager2;
930
931 if(solutionBuildManager == null)
932 {
933 return false;
934 }
935
936 IVsProjectCfg[] activeConfigs = new IVsProjectCfg[1];
937 ErrorHandler.ThrowOnFailure(solutionBuildManager.FindAct iveProjectCfg(IntPtr.Zero, IntPtr.Zero, hierarchy, activeConfigs));
938
939 IVsProjectCfg activeCfg = activeConfigs[0];
940
941 // Can it be that the activeCfg is null?
942 System.Diagnostics.Debug.Assert(activeCfg != null, "Cann ot find the active configuration");
943
944 string canonicalName;
945 ErrorHandler.ThrowOnFailure(activeCfg.get_CanonicalName( out canonicalName));
946
947 return ProjectConfig.TrySplitConfigurationCanonicalName( canonicalName, out configuration, out platform);
948 }
949
950 /// <summary>
951 /// Determines whether the shell is in command line mode.
952 /// </summary>
953 /// <param name="serviceProvider">A reference to a Service Provi der.</param>
954 /// <returns>true if the shell is in command line mode. false ot herwise.</returns>
955 internal static bool IsShellInCommandLineMode(System.IServicePro vider serviceProvider)
956 {
957 if(serviceProvider == null)
958 {
959 throw new ArgumentNullException("serviceProvider ");
960 }
961
962 IVsShell shell = serviceProvider.GetService(typeof(SVsSh ell)) as IVsShell;
963 if(shell == null)
964 {
965 throw new InvalidOperationException();
966 }
967
968 object isInCommandLineModeAsObject;
969 ErrorHandler.ThrowOnFailure(shell.GetProperty((int)__VSS PROPID.VSSPROPID_IsInCommandLineMode, out isInCommandLineModeAsObject));
970
971 return ((bool)isInCommandLineModeAsObject);
972 }
973
974 /// <summary>
975 /// Saves the dialog state in the solution
976 /// </summary>
977 /// <param name="serviceProvider">A reference to a Service Provi der.</param>
978 /// <param name="projectLoadSecurityDialogState">The dialog stat e</param>
979 internal static void SaveDialogStateInSolution(IServiceProvider serviceProvider, _ProjectLoadSecurityDialogState projectLoadSecurityDialogState)
980 {
981 if(serviceProvider == null)
982 {
983 throw new ArgumentNullException("serviceProvider ");
984 }
985
986 IVsSolution solution = serviceProvider.GetService(typeof (SVsSolution)) as IVsSolution;
987
988 if(solution == null)
989 {
990 throw new InvalidOperationException();
991 }
992
993 ErrorHandler.ThrowOnFailure(solution.SetProperty((int)__ VSPROPID2.VSPROPID_ProjectLoadSecurityDialogState, projectLoadSecurityDialogStat e));
994 }
995
996 /// <summary>
997 /// Checks if the project location is secure.
998 /// </summary>
999 /// <param name="location">The project folder.</param>
1000 /// <returns>True if the project location is secure.</returns>
1001 internal static bool IsProjectLocationSecure(string location)
1002 {
1003 if(String.IsNullOrEmpty(location) || location.Length > N ativeMethods.MAX_PATH)
1004 {
1005 return false;
1006 }
1007
1008 Zone zone = Zone.CreateFromUrl(location);
1009 if(zone == null)
1010 {
1011 return false;
1012 }
1013
1014 // Now use the utilities from the msbuild api to check u s the path.
1015 Microsoft.VisualStudio.Build.ComInteropWrapper.Utilities utilities = new Microsoft.VisualStudio.Build.ComInteropWrapper.Utilities();
1016
1017 return utilities.CheckPath(location, (int)zone.SecurityZ one);
1018 }
1019 }
1020 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698