ICE 3.4.2
[php5-ice-freebsdport.git] / vsaddin / src / Util.cs
blobd7855721a702c29a2810122135ad75eeaabc8668
1 // **********************************************************************
2 //
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
4 //
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
7 //
8 // **********************************************************************
10 using System;
11 using System.Text;
12 using System.Collections.Generic;
13 using System.ComponentModel;
15 using EnvDTE;
16 using System.Windows.Forms;
17 using System.Runtime.InteropServices;
18 using System.IO;
19 using System.Diagnostics;
20 using Extensibility;
21 using EnvDTE80;
22 using Microsoft.VisualStudio;
23 using Microsoft.VisualStudio.CommandBars;
24 using Microsoft.VisualStudio.VCProjectEngine;
25 using Microsoft.VisualStudio.VCProject;
26 using Microsoft.VisualStudio.Shell;
27 using Microsoft.VisualStudio.Shell.Interop;
28 using System.Resources;
29 using System.Reflection;
30 using VSLangProj;
31 using System.Globalization;
33 using System.Collections;
34 using System.Runtime.InteropServices.ComTypes;
35 using Microsoft.CSharp;
36 using System.Xml;
38 namespace Ice.VisualStudio
40 public class ComponentList : List<string>
42 public ComponentList()
46 public ComponentList(string[] values)
48 foreach(string s in values)
50 Add(s);
54 public ComponentList(string value)
56 if(value == null)
58 value = "";
60 init(value, ';');
63 public ComponentList(string value, char separator)
65 init(value, separator);
68 public new void Add(string value)
70 value = value.Trim();
71 if(String.IsNullOrEmpty(value))
73 return;
75 if(!base.Contains(value))
77 base.Add(value);
81 public new bool Contains(string value)
83 string found = base.Find(delegate(string s)
85 return s.Equals(value.Trim(), StringComparison.CurrentCultureIgnoreCase);
86 });
87 return found != null;
90 public new bool Remove(string value)
92 value = value.Trim();
93 if(Contains(value))
95 return base.Remove(value);
97 return false;
100 private void init(string value, char separator)
102 Array items = value.Split(separator);
103 foreach(string s in items)
105 Add(s);
109 public override string ToString()
111 return ToString(';');
114 public string ToString(char separator)
116 if(this.Count == 0)
118 return "";
120 StringBuilder sb = new StringBuilder();
121 for(int cont = 0; cont < this.Count; ++cont)
123 sb.Append(this[cont]);
124 if(cont < this.Count - 1)
126 sb.Append(separator);
129 return sb.ToString();
132 public bool Equal(ComponentList other)
134 if(this.Count != other.Count)
136 return false;
138 bool equal = true;
139 for(int i = 0; i < this.Count; ++i)
141 string val1 = this[i];
142 string val2 = other[i];
143 if(val1 == null && val2 == null)
145 continue;
148 if(val1 == null || val2 == null)
150 equal = false;
151 break;
154 if(!val1.Equals(val2, StringComparison.CurrentCultureIgnoreCase))
156 equal = false;
157 break;
160 return equal;
164 public class IncludePathList : ComponentList
166 public IncludePathList()
167 : base()
171 public IncludePathList(string[] values)
172 : base(values)
176 public IncludePathList(string value)
177 : base(value, '|')
181 public override string ToString()
183 return base.ToString('|');
186 public bool Contains(Project project, string value)
188 string path = Util.absolutePath(project, value);
189 string found = base.Find(delegate(string s)
191 string other = Util.absolutePath(project, s);
192 return path.Equals(other, StringComparison.CurrentCultureIgnoreCase);
194 return found != null;
198 public static class Util
200 public enum msgLevel{ msgError, msgInfo, msgDebug };
202 public const string slice2cs = "slice2cs.exe";
203 public const string slice2cpp = "slice2cpp.exe";
204 public const string slice2sl = "slice2sl.exe";
207 // Property names used to persist project configuration.
209 public const string PropertyIce = "ZerocIce_Enabled";
210 public const string PropertyIceOutputDir = "ZerocIce_OutputDir";
211 public const string PropertyIceHeaderExt = "ZerocIce_HeaderExt";
212 public const string PropertyIceSourceExt = "ZerocIce_SourceExt";
213 public const string PropertyIceComponents = "ZerocIce_Components";
214 public const string PropertyIceExtraOptions = "ZerocIce_ExtraOptions";
215 public const string PropertyIceIncludePath = "ZerocIce_IncludePath";
216 public const string PropertyIceStreaming = "ZerocIce_Streaming";
217 public const string PropertyIceChecksum = "ZerocIce_Checksum";
218 public const string PropertyIceTie = "ZerocIce_Tie";
219 public const string PropertyIcePrefix = "ZerocIce_Prefix";
220 public const string PropertyIceDllExport = "ZerocIce_DllExport";
221 public const string PropertyVerboseLevel = "ZerocIce_VerboseLevel";
223 private static readonly string[] silverlightNames =
225 "IceSL"
228 public static string[] getSilverlightNames()
230 return (string[])silverlightNames.Clone();
233 private static readonly string[] cppNames =
235 "Freeze", "Glacier2", "Ice", "IceBox", "IceGrid", "IcePatch2",
236 "IceSSL", "IceStorm", "IceUtil"
239 public static string[] getCppNames()
241 return (string[])cppNames.Clone();
244 private static readonly string[] dotNetNames =
246 "Glacier2", "Ice", "IceBox", "IceGrid", "IcePatch2",
247 "IceSSL", "IceStorm"
250 private static readonly string[] dotNetCompactNames =
252 "Glacier2", "Ice", "IceBox", "IceGrid", "IcePatch2",
253 "IceStorm"
256 public static string[] getDotNetCompactNames()
258 return (string[])dotNetCompactNames.Clone();
261 public static string[] getDotNetNames()
263 return (string[])dotNetNames.Clone();
266 public static string getIceSlHome()
269 // For Silverlight projects Ice Home is always set to the value of ICE_SL_HOME
270 // environment variable.
272 return Environment.ExpandEnvironmentVariables("%ICE_SL_HOME%");
275 public static string getIceHome()
277 string defaultIceHome = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
278 if(defaultIceHome.EndsWith("\\vsaddin", StringComparison.CurrentCultureIgnoreCase))
280 defaultIceHome = defaultIceHome.Substring(0, defaultIceHome.Length - "\\vsaddin".Length);
282 return defaultIceHome;
285 public static string getProjectOutputDirRaw(Project project)
287 return getProjectProperty(project, Util.PropertyIceOutputDir, "", false);
290 public static string getProjectOutputDir(Project project)
292 String path = getProjectOutputDirRaw(project);
293 if(containsEnvironmentVars(path))
295 path = expandEnvironmentVars(path);
297 return path;
300 public static string getProjectAbsoluteOutputDir(Project project)
302 String path = getProjectOutputDir(project);
303 if(!Path.IsPathRooted(path))
305 path = Util.absolutePath(project, path);
307 return path;
310 public static VCPropertySheet findPropertySheet(IVCCollection propertySheets, string sheetName)
312 VCPropertySheet value = null;
313 foreach(VCPropertySheet sheet in propertySheets)
315 if(sheet == null || String.IsNullOrEmpty(sheet.Name))
317 continue;
319 if(sheet.Name == sheetName)
321 value = sheet;
322 break;
325 return value;
329 // This will add the Ice property sheet to the project.
331 public static void addIcePropertySheet(Project project)
333 VCProject vcProj = (VCProject)project.Object;
335 string propSheetFileName = "$(ALLUSERSPROFILE)\\ZeroC\\ice";
337 #if VS2008
338 propSheetFileName += ".vsprops";
339 #endif
341 #if VS2010
342 propSheetFileName += ".props";
343 #endif
347 // All project configurations must include ice.vsprops (vc90) or ice.props (vc100)
349 IVCCollection configurations = (IVCCollection)vcProj.Configurations;
350 foreach(VCConfiguration vcConfig in configurations)
352 VCPropertySheet newSheet = findPropertySheet(vcConfig.PropertySheets as IVCCollection, "ice");
353 if(newSheet == null)
355 #if VS2008
356 string inhertiedPropertySheets = vcConfig.InheritedPropertySheets;
357 if(String.IsNullOrEmpty(inhertiedPropertySheets) || !inhertiedPropertySheets.Contains(propSheetFileName))
359 if(!String.IsNullOrEmpty(inhertiedPropertySheets) && !inhertiedPropertySheets.EndsWith(";"))
361 inhertiedPropertySheets += " ; ";
363 inhertiedPropertySheets += propSheetFileName;
364 vcConfig.InheritedPropertySheets = inhertiedPropertySheets;
366 #endif
368 #if VS2010
369 newSheet = vcConfig.AddPropertySheet(propSheetFileName);
370 #endif
376 public static string getCsBinDir(Project project)
378 string binDir = "";
379 if(isVBSmartDeviceProject(project) || isCSharpSmartDeviceProject(project))
381 binDir = _csCompactFrameworkBinDirs;
383 else
385 binDir = _csBinDirs;
387 return Path.Combine(Util.getIceHome(), binDir);
390 public static string getPathRelativeToProject(ProjectItem item)
392 StringBuilder path = new StringBuilder();
393 if(item != null)
395 path.Append(Util.getPathRelativeToProject(item, item.ContainingProject.ProjectItems));
397 return path.ToString();
400 public static string getPathRelativeToProject(ProjectItem item, ProjectItems items)
402 StringBuilder path = new StringBuilder();
403 foreach(ProjectItem i in items)
405 if(i == item)
407 if(path.Length > 0)
409 path.Append("\\");
411 path.Append(i.Name);
412 break;
414 else if(Util.isProjectItemFilter(i) || Util.isProjectItemFolder(i))
416 string token = Util.getPathRelativeToProject(item, i.ProjectItems);
417 if(!String.IsNullOrEmpty(token))
419 path.Append(i.Name);
420 path.Append("\\");
421 path.Append(token);
422 break;
426 return path.ToString();
429 private static readonly string iceIncludeDir = "$(IceHome)\\include";
431 public static bool addCppIncludes(VCCLCompilerTool tool, Project project)
433 if(tool == null || project == null)
435 return false;
439 bool changed = false;
440 ComponentList includes = new ComponentList(tool.AdditionalIncludeDirectories);
443 if(!includes.Contains(iceIncludeDir) && !includes.Contains(quote(iceIncludeDir)))
445 changed = true;
446 includes.Add(quote(iceIncludeDir));
449 string outputDir = getProjectOutputDirRaw(project);
450 if(outputDir.Equals(""))
452 outputDir = ".";
455 if(!includes.Contains(outputDir) && !includes.Contains(quote(outputDir)))
457 changed = true;
458 includes.Add(outputDir);
461 if(changed)
463 tool.AdditionalIncludeDirectories = includes.ToString();
465 return changed;
468 public static void removeCppIncludes(VCCLCompilerTool tool, string iceHome, string generatedDir)
470 if(tool == null || String.IsNullOrEmpty(tool.AdditionalIncludeDirectories))
472 return;
475 bool changed = false;
477 ComponentList includes = new ComponentList(tool.AdditionalIncludeDirectories);
479 if(includes.Remove(quote(iceHome + "\\include")))
481 changed = true;
484 if(includes.Remove(iceHome + "\\include"))
486 changed = true;
489 if(!generatedDir.Equals("."))
491 if(includes.Remove(generatedDir))
493 changed = true;
497 if(changed)
499 tool.AdditionalIncludeDirectories = includes.ToString();
503 public static void removeIcePropertySheet(VCConfiguration configuration)
505 if(configuration == null)
507 return;
510 #if VS2008
511 ComponentList sheets = new ComponentList(configuration.InheritedPropertySheets);
512 if(sheets.Remove("$(ALLUSERSPROFILE)\\ZeroC\\ice.vsprops"))
514 configuration.InheritedPropertySheets = sheets.ToString();
516 #endif
517 #if VS2010
518 VCPropertySheet sheet = null;
519 IVCCollection sheets = (IVCCollection)configuration.PropertySheets;
520 foreach(VCPropertySheet s in sheets)
522 if(!s.PropertySheetFile.Equals(configuration.Evaluate("$(ALLUSERSPROFILE)\\ZeroC\\ice.props"),
523 StringComparison.CurrentCultureIgnoreCase))
525 continue;
527 sheet = s;
528 break;
531 if(sheet != null)
533 configuration.RemovePropertySheet(sheet);
535 #endif
538 private static readonly string _csBinDirs = "\\bin\\";
539 private static readonly string _csCompactFrameworkBinDirs = "\\bin\\cf\\";
541 public static bool addDotNetReference(Project project, string component, string iceHome, bool development)
543 if(project == null || String.IsNullOrEmpty(component))
545 return false;
548 string csBinDir = null;
549 if(isVBSmartDeviceProject(project) || isCSharpSmartDeviceProject(project))
551 csBinDir = _csCompactFrameworkBinDirs;
553 else
555 csBinDir = _csBinDirs;
559 string reference = iceHome + csBinDir + component + ".dll";
560 if (File.Exists(reference))
562 VSLangProj.VSProject vsProject = (VSLangProj.VSProject)project.Object;
565 Reference r = vsProject.References.Add(reference);
566 if (development)
568 r.CopyLocal = false;
570 return true;
572 catch (COMException ex)
574 Console.WriteLine(ex);
578 MessageBox.Show("Could not locate '" + component +
579 ".dll'. in '" + Path.GetDirectoryName(reference) + "'",
580 "Ice Visual Studio Add-in", MessageBoxButtons.OK,
581 MessageBoxIcon.Error,
582 MessageBoxDefaultButton.Button1,
583 (MessageBoxOptions)0);
584 return false;
587 public static bool removeDotNetReference(Project project, string component)
589 if(project == null || String.IsNullOrEmpty(component))
591 return false;
594 foreach(Reference r in ((VSProject)project.Object).References)
596 if(r.Name.Equals(component, StringComparison.OrdinalIgnoreCase))
598 r.Remove();
599 return true;
602 return false;
605 public static void addCppLib(VCLinkerTool tool, string component, bool debug)
607 if(tool == null || String.IsNullOrEmpty(component))
609 return;
612 if(Array.BinarySearch(Util.getCppNames(), component, StringComparer.CurrentCultureIgnoreCase) < 0)
614 return;
617 string libName = component;
618 if(debug)
620 libName += "d";
622 libName += ".lib";
624 string additionalDependencies = tool.AdditionalDependencies;
625 if(String.IsNullOrEmpty(additionalDependencies))
627 additionalDependencies = "";
630 ComponentList components = new ComponentList(additionalDependencies.Split(' '));
631 if(!components.Contains(libName))
633 components.Add(libName);
634 additionalDependencies = components.ToString(' ');
635 tool.AdditionalDependencies = additionalDependencies;
639 public static bool removeCppLib(VCLinkerTool tool, string component, bool debug)
641 if(tool == null || String.IsNullOrEmpty(tool.AdditionalDependencies))
643 return false;
646 string libName = component;
647 if(debug)
649 libName += "d";
651 libName += ".lib";
653 ComponentList components = new ComponentList(tool.AdditionalDependencies.Split(' '));
654 if(components.Contains(libName))
656 components.Remove(libName);
657 tool.AdditionalDependencies = components.ToString(' ');
658 return true;
660 return false;
664 // Add the Ice bin path to the debug environment.
666 // Note: Only the last setting in the environment has effect.
668 public static void addIceCppEnvironment(VCDebugSettings debugSettings, Project project,
669 bool x64)
671 if(debugSettings == null || project == null)
673 return;
675 String value = "PATH=" + cppBinDir(project, x64);
676 if(String.IsNullOrEmpty(debugSettings.Environment))
678 debugSettings.Environment = value;
679 return;
681 if(value.Equals(debugSettings.Environment))
683 return;
686 if(String.IsNullOrEmpty(debugSettings.Environment))
688 debugSettings.Environment = value;
689 return;
692 ComponentList envs = new ComponentList(debugSettings.Environment, '\n');
694 string path = "";
697 // Find the last in the list that begins: "PATH=" accounting for case and whitespace.
699 int index = -1;
700 for(int i = 0; i < envs.Count; ++i)
702 string s = envs[i].Trim();
703 if(s.StartsWith("PATH", StringComparison.CurrentCultureIgnoreCase))
705 if(s.Substring("PATH".Length).Trim().StartsWith("=", StringComparison.CurrentCultureIgnoreCase))
707 path = s;
708 index = i;
713 if(index == -1)
715 envs.Add("PATH=" + cppBinDir(project, x64));
717 else
719 string binDir = cppBinDir(project, x64);
720 ComponentList paths = new ComponentList(assignmentValue(path), ';');
721 while(paths.Contains(binDir))
723 paths.Remove(binDir);
725 path = "PATH=" + binDir + Path.PathSeparator + paths.ToString(Path.PathSeparator);
726 path = path.TrimEnd(Path.PathSeparator);
727 envs[index] = path;
730 value = envs.ToString('\n');
731 if(!debugSettings.Environment.Equals(value))
733 debugSettings.Environment = value;
735 return;
738 private static string removeFromPath(string path, string dir)
740 ComponentList list = new ComponentList(path.Split(Path.PathSeparator));
741 while(list.Contains(dir))
743 list.Remove(dir);
745 return list.ToString(Path.PathSeparator);
748 private static string assignmentValue(string expr)
750 int i = expr.IndexOf('=');
751 if(i < 0)
753 return "";
757 return expr.Substring(i).Substring(1).Trim();
759 catch(ArgumentOutOfRangeException)
761 return "";
765 private static string prependToPath(string path, string dir)
767 path = removeFromPath(path, dir);
768 return dir + Path.PathSeparator + path;
771 public static string cppBinDir(Project project, bool x64)
773 string cppBinDir = Path.Combine("$(IceHome)", "bin");
774 #if VS2010
775 cppBinDir = Path.Combine(cppBinDir, "vc100");
776 #endif
777 if(x64)
779 cppBinDir = Path.Combine(cppBinDir, "x64");
781 return cppBinDir;
784 public static void removeIceCppEnvironment(VCDebugSettings debugSettings, string iceHome)
786 if(debugSettings == null || String.IsNullOrEmpty(debugSettings.Environment))
788 return;
791 string[] _cppBinDirs =
793 "bin",
794 "bin\\x64",
795 "bin\\vc100",
796 "bin\\vc100\\x64",
797 "cpp\\bin",
800 ComponentList envs = new ComponentList(debugSettings.Environment, '\n');
801 /* Find the last in the list that begins: "PATH=" accounting for case and whitespace. */
802 string path = "";
803 int index = -1;
804 for(int i = 0; i < envs.Count; ++i)
806 string s = envs[i];
807 if(s.StartsWith("PATH", StringComparison.CurrentCultureIgnoreCase))
809 if(s.Substring("PATH".Length).Trim().StartsWith("=", StringComparison.CurrentCultureIgnoreCase))
811 path = s;
812 index = i;
817 if(index == -1)
819 return;
822 foreach(string dir in _cppBinDirs)
824 path = "PATH=" + removeFromPath(assignmentValue(path).Trim(), Path.Combine(iceHome, dir));
827 if(path.Equals("PATH="))
829 envs.RemoveAt(index);
831 else
833 envs[index] = path;
836 String value = envs.ToString();
837 if(!debugSettings.Environment.Equals(value))
839 debugSettings.Environment = value;
841 return;
844 public static bool addIceCppLibraryDir(VCLinkerTool tool, Project project, bool x64)
846 if(tool == null || project == null)
848 return false;
851 string iceLibDir = "$(IceHome)\\lib";
852 #if VS2010
853 iceLibDir += "\\vc100";
854 #endif
855 if(x64)
857 iceLibDir += "\\x64";
860 string additionalLibraryDirectories = tool.AdditionalLibraryDirectories;
861 if(String.IsNullOrEmpty(additionalLibraryDirectories))
863 tool.AdditionalLibraryDirectories = quote(iceLibDir);
864 return true;
868 // Remove Ice lib directories that doesn't match the current ice lib dir.
871 ComponentList libs = new ComponentList(additionalLibraryDirectories);
872 ComponentList remove = new ComponentList();
874 foreach(string lib in libs)
876 if(lib.Equals(iceLibDir) ||
877 lib.Equals(quote(iceLibDir)))
879 continue;
881 if(lib.StartsWith("$(IceHome)") ||
882 lib.StartsWith("\"$(IceHome)"))
884 remove.Add(lib);
888 bool changed = false;
889 foreach(string lib in remove)
891 if(libs.Remove(lib))
893 changed = true;
897 if(!libs.Contains(iceLibDir) &&
898 !libs.Contains(quote(iceLibDir)))
900 libs.Add(quote(iceLibDir));
901 changed = true;
904 if(changed)
906 tool.AdditionalLibraryDirectories = libs.ToString();
909 return changed;
912 public static void removeIceCppLibraryDir(VCLinkerTool tool, string iceHome)
914 if(tool == null || String.IsNullOrEmpty(tool.AdditionalLibraryDirectories))
916 return;
919 string[] _cppLibDirs =
921 "lib",
922 "lib\\x64",
923 "lib\\vc100",
924 "lib\\vc100\\x64"
927 bool changed = false;
928 ComponentList libs = new ComponentList(tool.AdditionalLibraryDirectories);
929 foreach(string dir in _cppLibDirs)
931 if(libs.Remove(quote(Path.Combine(iceHome, dir))))
933 changed = true;
935 if(libs.Remove(Path.Combine(iceHome, dir)))
937 changed = true;
940 if(changed)
942 tool.AdditionalLibraryDirectories = libs.ToString();
946 public static bool isSliceFilename(string s)
948 return s != null && s.EndsWith(".ice", StringComparison.CurrentCultureIgnoreCase);
951 public static bool equalPath(string p1, string p2, string basePath)
953 if(p1 == p2)
955 return true;
958 if(String.IsNullOrEmpty(p1) || String.IsNullOrEmpty(p2))
960 return false;
964 // Convert both paths to absolute paths if necessary
966 if(!Path.IsPathRooted(p1))
968 p1 = Path.Combine(basePath, p1);
971 if(!Path.IsPathRooted(p2))
973 p2 = Path.Combine(basePath, p2);
979 // Note that in Windows white space at the beginning or end of a file are ignored.
980 // When comparing the filenames "Foo ", " Foo", and "foo", all refer to the same file.
982 // We also need to trim / (directory separator) from the end in case it's present.
984 return 0 == String.Compare(
985 Path.GetFullPath(p1).Trim().TrimEnd(Path.DirectorySeparatorChar),
986 Path.GetFullPath(p2).Trim().TrimEnd(Path.DirectorySeparatorChar),
987 StringComparison.CurrentCultureIgnoreCase);
989 catch(ArgumentException)
992 catch(NotSupportedException)
995 catch(System.Security.SecurityException)
998 catch(PathTooLongException)
1001 return false;
1004 public static bool isSliceBuilderEnabled(Project project)
1006 return Util.getProjectPropertyAsBool(project, Util.PropertyIce);
1009 public static bool isCSharpProject(Project project)
1011 if(project == null)
1013 return false;
1016 if(String.IsNullOrEmpty(project.Kind))
1018 return false;
1021 return project.Kind == VSLangProj.PrjKind.prjKindCSharpProject;
1024 public static bool isCSharpSmartDeviceProject(Project project)
1026 return hasProjecType(project, vsSmartDeviceCSharp);
1029 public static bool isVBSmartDeviceProject(Project project)
1031 return hasProjecType(project, vsSmartDeviceVB);
1034 public static bool isVBProject(Project project)
1036 if(project == null)
1038 return false;
1041 if(String.IsNullOrEmpty(project.Kind))
1043 return false;
1046 return project.Kind == VSLangProj.PrjKind.prjKindVBProject;
1049 public static bool isSilverlightProject(Project project)
1051 if(!Util.isCSharpProject(project))
1053 return false;
1056 Array extenders = (Array)project.ExtenderNames;
1057 foreach(string s in extenders)
1059 if(String.IsNullOrEmpty(s))
1061 continue;
1063 if(s.Equals("SilverlightProject"))
1065 return true;
1068 return false;
1071 public static bool isCppProject(Project project)
1073 if(project == null)
1075 return false;
1078 if(String.IsNullOrEmpty(project.Kind))
1080 return false;
1082 return project.Kind == vcContextGuids.vcContextGuidVCProject;
1085 public static bool isProjectItemFolder(ProjectItem item)
1087 if(item == null)
1089 return false;
1092 if(String.IsNullOrEmpty(item.Kind))
1094 return false;
1096 return item.Kind == "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}";
1099 public static bool isProjectItemFilter(ProjectItem item)
1101 if(item == null)
1103 return false;
1106 if(String.IsNullOrEmpty(item.Kind))
1108 return false;
1110 return item.Kind == "{6BB5F8F0-4483-11D3-8BCF-00C04F8EC28C}";
1113 public static bool isProjectItemFile(ProjectItem item)
1115 if(item == null)
1117 return false;
1120 if(String.IsNullOrEmpty(item.Kind))
1122 return false;
1124 return item.Kind == "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}";
1127 public static bool hasItemNamed(ProjectItems items, string name)
1129 bool found = false;
1130 foreach(ProjectItem item in items)
1132 if(item == null)
1134 continue;
1137 if(item.Name == null)
1139 continue;
1142 if(item.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
1144 found = true;
1145 break;
1148 return found;
1151 public static ProjectItem findItem(string path)
1153 Builder builder = Connect.getBuilder();
1154 DTE dte = builder.getCurrentDTE();
1155 if(dte == null)
1157 return null;
1159 if(dte.Solution == null)
1161 return null;
1164 List<Project> projects = Util.getProjects(dte.Solution);
1165 ProjectItem item = null;
1166 foreach(Project project in projects)
1168 item = findItem(path, project.ProjectItems);
1169 if(item != null)
1171 break;
1174 return item;
1177 public static ProjectItem findItem(string path, ProjectItems items)
1179 if(String.IsNullOrEmpty(path))
1181 return null;
1183 ProjectItem item = null;
1184 foreach(ProjectItem i in items)
1186 if(i == null)
1188 continue;
1190 else if(Util.isProjectItemFile(i))
1192 string fullPath = i.Properties.Item("FullPath").Value.ToString();
1193 Project project = i.ContainingProject;
1194 if(Util.equalPath(fullPath, path, Path.GetDirectoryName(project.FileName)))
1196 item = i;
1197 break;
1200 else if(Util.isProjectItemFolder(i))
1202 string p = Path.GetDirectoryName(i.Properties.Item("FullPath").Value.ToString());
1203 Project project = i.ContainingProject;
1204 if(Util.equalPath(p, path, Path.GetDirectoryName(project.FileName)))
1206 item = i;
1207 break;
1210 item = findItem(path, i.ProjectItems);
1211 if(item != null)
1213 break;
1216 else if(Util.isProjectItemFilter(i))
1218 string p = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(i.ContainingProject.FileName),
1219 Util.getPathRelativeToProject(i)));
1221 Project project = i.ContainingProject;
1222 if(Util.equalPath(p, path, Path.GetDirectoryName(project.FileName)))
1224 item = i;
1225 break;
1228 item = findItem(path, i.ProjectItems);
1229 if(item != null)
1231 break;
1235 return item;
1238 public static VCFile findVCFile(IVCCollection files, string name, string fullPath)
1240 VCFile vcFile = null;
1241 foreach(VCFile file in files)
1243 if(file.ItemName == name)
1245 Project project = (Project)((VCProject) file.project).Object;
1246 if(!Util.equalPath(file.FullPath, fullPath, Path.GetDirectoryName(project.FileName)))
1248 file.Remove();
1249 break;
1251 vcFile = file;
1252 break;
1255 return vcFile;
1258 public static string relativePath(Project project, string absoluteFilePath)
1260 if(absoluteFilePath == null)
1262 return "";
1265 if(project == null)
1267 return absoluteFilePath;
1270 return relativePath(Path.GetDirectoryName(project.FileName), absoluteFilePath);
1273 public static string relativePath(string mainDirPath, string absoluteFilePath)
1275 if(absoluteFilePath == null)
1277 return "";
1280 if(mainDirPath == null)
1282 return absoluteFilePath;
1285 if(!Path.IsPathRooted(absoluteFilePath))
1287 return absoluteFilePath;
1290 mainDirPath = Path.GetFullPath(mainDirPath).Trim(Path.DirectorySeparatorChar);
1291 absoluteFilePath = Path.GetFullPath(absoluteFilePath).Trim(Path.DirectorySeparatorChar);
1293 string[] firstPathParts = mainDirPath.Split(Path.DirectorySeparatorChar);
1294 string[] secondPathParts = absoluteFilePath.Split(Path.DirectorySeparatorChar);
1296 int sameCounter = 0;
1297 while(sameCounter < Math.Min(firstPathParts.Length, secondPathParts.Length) &&
1298 String.Equals(firstPathParts[sameCounter], secondPathParts[sameCounter],
1299 StringComparison.CurrentCultureIgnoreCase))
1301 ++sameCounter;
1304 // Different volumes, relative path not possible.
1305 if(sameCounter == 0)
1307 return absoluteFilePath;
1310 // Pop back up to the common point.
1311 string newPath = "." + Path.DirectorySeparatorChar;
1312 for(int i = sameCounter; i < firstPathParts.Length; ++i)
1314 newPath += ".." + Path.DirectorySeparatorChar;
1317 // Descend to the target.
1318 for(int i = sameCounter; i < secondPathParts.Length; ++i)
1320 newPath += secondPathParts[i] + Path.DirectorySeparatorChar;
1322 return newPath.TrimEnd(Path.DirectorySeparatorChar);
1325 // Relative paths are relative to project.
1326 // Inverse of Util.relativePath().
1327 public static string absolutePath(Project project, string path)
1329 if(Path.IsPathRooted(path)) // If path is absolute return that path
1331 return path;
1333 return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(project.FileName), path)).TrimEnd(
1334 Path.DirectorySeparatorChar);
1337 public static Project getSelectedProject(_DTE dte)
1339 Microsoft.VisualStudio.Shell.ServiceProvider sp = new Microsoft.VisualStudio.Shell.ServiceProvider(
1340 getCurrentDTE() as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
1341 IVsMonitorSelection selectionMonitor = sp.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection;
1344 // There isn't an open project.
1346 if(selectionMonitor == null)
1348 return null;
1351 Project project = null;
1352 IntPtr ppHier;
1353 uint pitemid;
1354 IVsMultiItemSelect ppMIS;
1355 IntPtr ppSC;
1356 if(ErrorHandler.Failed(selectionMonitor.GetCurrentSelection(out ppHier, out pitemid, out ppMIS, out ppSC)))
1358 return null;
1361 if(ppHier != IntPtr.Zero)
1363 IVsHierarchy hier = (IVsHierarchy)Marshal.GetObjectForIUnknown(ppHier);
1364 Marshal.Release(ppHier);
1365 object obj;
1366 hier.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out obj);
1367 if(obj != null)
1369 project = obj as EnvDTE.Project;
1373 if(ppSC != IntPtr.Zero)
1375 Marshal.Release(ppSC);
1378 return project;
1381 public static ProjectItem getSelectedProjectItem(_DTE dte)
1383 Microsoft.VisualStudio.Shell.ServiceProvider sp = new Microsoft.VisualStudio.Shell.ServiceProvider(
1384 getCurrentDTE() as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
1385 IVsMonitorSelection selectionMonitor = sp.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection;
1388 // There isn't an open project.
1390 if(selectionMonitor == null)
1392 return null;
1395 ProjectItem projectItem = null;
1396 IntPtr ppHier;
1397 uint pitemid;
1398 IVsMultiItemSelect ppMIS;
1399 IntPtr ppSC;
1400 if(ErrorHandler.Failed(selectionMonitor.GetCurrentSelection(out ppHier, out pitemid, out ppMIS, out ppSC)))
1402 return null;
1405 if(ppHier != IntPtr.Zero)
1407 IVsHierarchy hier = (IVsHierarchy)Marshal.GetObjectForIUnknown(ppHier);
1408 Marshal.Release(ppHier);
1409 object obj;
1410 hier.GetProperty(pitemid, (int)__VSHPROPID.VSHPROPID_ExtObject, out obj);
1411 if(obj != null)
1413 projectItem = obj as EnvDTE.ProjectItem;
1417 if(ppSC != IntPtr.Zero)
1419 Marshal.Release(ppSC);
1422 return projectItem;
1425 public static bool updateOutputDir(Project project, String outputDir)
1428 // Note that ouputDir could be empty, which means the project dir will
1429 // be used as the output directory, and is also the default.
1431 if(project == null || outputDir == null)
1433 return false;
1436 Util.cleanProject(project, true);
1438 string oldOutputDir = getProjectAbsoluteOutputDir(project);
1440 string projectDir = Path.GetDirectoryName(project.FileName);
1442 // Remove old output directory if necessary.
1443 if(!equalPath(oldOutputDir, projectDir, projectDir) &&
1444 isEmptyDir(oldOutputDir))
1446 // In C# projects, diretories are project items, but not in C++ projects.
1447 if(isCSharpProject(project))
1449 ProjectItem item = findItem(oldOutputDir, project.ProjectItems);
1450 if(item != null)
1452 item.Delete();
1455 if(Directory.Exists(oldOutputDir))
1457 Directory.Delete(oldOutputDir, true);
1461 if(isCppProject(project))
1463 // We must remove old output directory from C++ project include path.
1464 removeCppIncludes(project);
1467 Util.setProjectProperty(project, Util.PropertyIceOutputDir, outputDir);
1469 if(isCppProject(project))
1471 // We must add the new output directory to C++ project include path.
1472 addCppIncludes(project);
1475 return true;
1478 public static void removeCppIncludes(Project project)
1480 if(!isCppProject(project))
1482 return;
1485 VCProject vcProject = (VCProject)project.Object;
1486 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
1487 foreach(VCConfiguration conf in configurations)
1489 if(conf != null)
1491 VCCLCompilerTool compilerTool =
1492 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
1493 Util.removeCppIncludes(compilerTool, "$(IceHome)", Util.getProjectOutputDirRaw(project));
1498 public static void addCppIncludes(Project project)
1500 if(!isCppProject(project))
1502 return;
1505 VCProject vcProject = (VCProject)project.Object;
1506 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
1507 foreach(VCConfiguration conf in configurations)
1509 if(conf != null)
1511 VCCLCompilerTool compilerTool =
1512 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
1513 Util.addCppIncludes(compilerTool, project);
1519 // Return true if the directory doesn't contain any
1520 // files. We use this to check if it is safe to delete
1521 // the output-dir after the user changes the setting.
1523 public static bool isEmptyDir(String path)
1525 if(String.IsNullOrEmpty(path))
1527 return false;
1530 if(!Directory.Exists(path))
1532 return false;
1535 DirectoryInfo dir = new DirectoryInfo(path);
1536 FileInfo[] files = dir.GetFiles();
1537 if(files.Length == 0)
1539 return true;
1541 bool empty = true;
1542 foreach(FileInfo f in files)
1544 if(File.Exists(f.FullName))
1546 empty = false;
1547 break;
1549 else if(Directory.Exists(f.FullName))
1551 empty = isEmptyDir(f.FullName);
1552 if(!empty)
1554 break;
1558 return empty;
1564 // The CopyLocal property doesn't work consistently, as sometimes it is set to false
1565 // when the reference isn't found. This happens when project demos are fisrt
1566 // opened, as at this point the reference path has not been fixed to use the
1567 // correct IceHome value. This method returns the private metadata of a
1568 // Reference from the project file; this value doesn't change as does CopyLocal.
1571 #if VS2010
1573 // This method requires .NET 4. Microsoft.Build.BuildEngine is deprecated
1574 // in .NET 4, so this method uses the new API Microsoft.Build.Evaluation.
1576 private static bool getCopyLocal(Project project, string name)
1578 Microsoft.Build.Evaluation.ProjectItem referenceItem = null;
1580 Microsoft.Build.Evaluation.Project p =
1581 Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.LoadProject(project.FullName);
1583 foreach(Microsoft.Build.Evaluation.ProjectItem item in p.Items)
1585 if(!item.ItemType.Equals("Reference"))
1587 continue;
1590 if(!item.HasMetadata("private"))
1592 continue;
1595 string[] tokens = item.EvaluatedInclude.Split(',');
1596 if(tokens.Length <= 0)
1598 continue;
1601 if(!tokens[0].Trim().Equals(name, StringComparison.CurrentCultureIgnoreCase))
1603 continue;
1606 referenceItem = item;
1608 if(referenceItem != null)
1610 break;
1614 if(referenceItem != null)
1616 return referenceItem.GetMetadata("Private").EvaluatedValue.Equals(true.ToString(),
1617 StringComparison.CurrentCultureIgnoreCase);
1619 return true;
1621 #elif VS2008
1623 // This method uses the .NET 3.5 API Microsoft.Build.BuildEngine. This API
1624 // should not be used with .NET 4 because it has been deprecated.
1626 private static bool getCopyLocal(Project project, string name)
1628 Microsoft.Build.BuildEngine.BuildItem referenceItem = null;
1629 Microsoft.Build.BuildEngine.Project p =
1630 Microsoft.Build.BuildEngine.Engine.GlobalEngine.GetLoadedProject(project.FileName);
1632 foreach(Microsoft.Build.BuildEngine.BuildItemGroup itemGroup in p.ItemGroups)
1634 foreach(Microsoft.Build.BuildEngine.BuildItem item in itemGroup)
1636 if(!item.Name.Equals("Reference"))
1638 continue;
1641 string[] tokens = item.Include.Split(',');
1642 if(tokens.Length <= 0)
1644 continue;
1647 if(!tokens[0].Trim().Equals(name, StringComparison.CurrentCultureIgnoreCase))
1649 continue;
1652 referenceItem = item;
1654 if(referenceItem != null)
1656 break;
1659 if(referenceItem != null)
1661 break;
1664 if(referenceItem != null)
1666 return referenceItem.GetMetadata("Private").Equals(true.ToString(),
1667 StringComparison.CurrentCultureIgnoreCase);
1669 return true;
1671 #endif
1672 private static void setCopyLocal(Project project, string name, bool copyLocal)
1674 VSLangProj.VSProject vsProject = (VSLangProj.VSProject)project.Object;
1675 foreach(Reference r in vsProject.References)
1677 if(r.Name.Equals(name))
1679 r.CopyLocal = copyLocal;
1680 break;
1685 public static int getProjectPropertyAsInt(Project project, string name)
1687 int value = -1;
1690 value = Convert.ToInt32(Util.getProjectProperty(project, name), CultureInfo.InvariantCulture);
1692 catch(FormatException)
1695 catch(OverflowException)
1698 return value;
1701 public static bool getProjectPropertyAsBool(Project project, string name)
1703 return Util.getProjectProperty(project, name).Equals(
1704 true.ToString(), StringComparison.CurrentCultureIgnoreCase);
1707 public static string getProjectProperty(Project project, string name)
1709 return Util.getProjectProperty(project, name, "", true);
1712 public static string getProjectProperty(Project project, string name, string defaultValue)
1714 return Util.getProjectProperty(project, name, defaultValue, true);
1717 public static string getProjectProperty(Project project, string name, string defaultValue, bool update)
1719 if(project == null || String.IsNullOrEmpty(name) || project.Globals == null)
1721 return defaultValue;
1724 if(project.Globals.get_VariableExists(name))
1726 return project.Globals[name].ToString();
1729 if(update)
1731 if(!String.IsNullOrEmpty(defaultValue))
1733 project.Globals[name] = defaultValue;
1734 if(!project.Globals.get_VariablePersists(name))
1736 project.Globals.set_VariablePersists(name, true);
1740 return defaultValue;
1743 public static void setProjectProperty(Project project, string name, string value)
1745 if(project == null || String.IsNullOrEmpty(name) || project.Globals == null)
1747 return;
1749 if(String.IsNullOrEmpty(value))
1751 if(project.Globals.get_VariableExists(name))
1753 project.Globals.set_VariablePersists(name, false);
1756 else if(!project.Globals.get_VariableExists(name) || (string)project.Globals[name] != value)
1758 project.Globals[name] = value;
1759 if(!project.Globals.get_VariablePersists(name))
1761 project.Globals.set_VariablePersists(name, true);
1767 // As the add-in evolves the code changes, but users still have project files
1768 // created by previous versions. This method is called when projects are opened
1769 // to account for old project files and to move them to the current requirements.
1771 public static void fix(Project p)
1773 if(p == null || p.Globals == null)
1775 return;
1778 // This variable was removed for 3.4.1.2.
1779 if(p.Globals.get_VariableExists("ZerocIce_HomeExpanded"))
1781 p.Globals.set_VariablePersists("ZerocIce_HomeExpanded", false);
1784 // This variable was removed for 3.4.2
1785 if(p.Globals.get_VariableExists("ZerocIce_Home"))
1787 string iceHome = expandEnvironmentVars(getProjectProperty(p, "ZerocIce_Home"));
1788 p.Globals.set_VariablePersists("ZerocIce_Home", false);
1790 if(Util.isCppProject(p))
1793 // Before 3.4.2 C++ project configurations don't use $(IceHome) macro,
1794 // we remove these old style settings.
1796 VCProject vcProject = (VCProject)p.Object;
1797 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
1800 // Path to property sheet used by VS 2010 projects before 3.4.2,
1801 // the property sheet is not longer needed and should be removed.
1803 string sheetFile = Util.absolutePath(p, "ice.props");
1805 foreach(VCConfiguration conf in configurations)
1807 if(conf == null)
1809 continue;
1812 VCCLCompilerTool compilerTool =
1813 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
1814 VCLinkerTool linkerTool = (VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool"));
1816 Util.removeIceCppEnvironment((VCDebugSettings)conf.DebugSettings, iceHome);
1817 Util.removeIceCppLibraryDir(linkerTool, iceHome);
1818 Util.removeCppIncludes(compilerTool, iceHome, Util.getProjectOutputDirRaw(p));
1821 // Remove ice.props, old property sheet used by VS 2010
1822 // from all project configurations.
1824 #if VS2010
1825 VCPropertySheet sheet = null;
1826 IVCCollection sheets = (IVCCollection)conf.PropertySheets;
1827 foreach(VCPropertySheet s in sheets)
1829 if(Util.absolutePath(p, s.PropertySheetFile).Equals(sheetFile))
1831 sheet = s;
1832 break;
1836 if(sheet != null)
1838 conf.RemovePropertySheet(sheet);
1840 #endif
1844 // If the old property sheet exists delete it from disk.
1846 if(File.Exists(sheetFile))
1850 File.Delete(sheetFile);
1852 catch(IOException)
1859 // This feature was made more general for 3.4.1.2.
1860 if(p.Globals.get_VariableExists("ZerocIce_ConsoleOutput"))
1862 if(!p.Globals.get_VariableExists(PropertyVerboseLevel))
1864 setProjectProperty(p, PropertyVerboseLevel, "0");
1865 if(getProjectPropertyAsBool(p, "ZerocIce_ConsoleOutput"))
1867 setProjectProperty(p, PropertyVerboseLevel, "1");
1870 p.Globals.set_VariablePersists("ZerocIce_ConsoleOutput", false);
1874 public static String getPrecompileHeader(Project project)
1876 string preCompiledHeader = "";
1878 VCConfiguration configuration = getActiveVCConfiguration(project);
1879 if(configuration == null)
1881 return preCompiledHeader;
1884 VCCLCompilerTool compilerTool =
1885 (VCCLCompilerTool)(((IVCCollection)configuration.Tools).Item("VCCLCompilerTool"));
1886 if(compilerTool == null)
1888 return preCompiledHeader;
1891 if(compilerTool.UsePrecompiledHeader == pchOption.pchCreateUsingSpecific ||
1892 compilerTool.UsePrecompiledHeader == pchOption.pchUseUsingSpecific)
1894 preCompiledHeader = compilerTool.PrecompiledHeaderThrough;
1897 return preCompiledHeader;
1900 public static ComponentList getIceCppComponents(Project project)
1902 ComponentList components = new ComponentList();
1903 ConfigurationManager configManager = project.ConfigurationManager;
1904 Configuration activeConfig = (Configuration)configManager.ActiveConfiguration;
1906 VCProject vcProject = (VCProject)project.Object;
1907 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
1908 foreach(VCConfiguration conf in configurations)
1910 if(conf == null)
1912 continue;
1914 if(String.IsNullOrEmpty(conf.Name))
1916 continue;
1918 if(!conf.Name.Equals(activeConfig.ConfigurationName + "|" + activeConfig.PlatformName))
1920 continue;
1923 VCCLCompilerTool compilerTool =
1924 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
1925 VCLinkerTool linkerTool = (VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool"));
1926 if(linkerTool == null || compilerTool == null)
1928 break;
1931 if(String.IsNullOrEmpty(linkerTool.AdditionalDependencies))
1933 break;
1936 bool debug = isDebug(compilerTool.RuntimeLibrary);
1938 List<string> componentNames = new List<string>(linkerTool.AdditionalDependencies.Split(' '));
1939 foreach(string s in componentNames)
1941 if(String.IsNullOrEmpty(s))
1943 continue;
1946 int index = s.LastIndexOf('.');
1947 if(index <= 0)
1949 continue;
1952 string libName = s.Substring(0, index);
1953 if(libName.EndsWith("d"))
1955 libName = libName.Substring(0, libName.Length - 1);
1957 if(String.IsNullOrEmpty(libName))
1959 continue;
1962 if(Array.BinarySearch(Util.getCppNames(), libName, StringComparer.CurrentCultureIgnoreCase) < 0)
1964 continue;
1966 components.Add(libName.Trim());
1969 return components;
1972 public static ComponentList getIceSilverlightComponents(Project project)
1974 ComponentList components = new ComponentList();
1975 if(project == null)
1977 return components;
1980 VSLangProj.VSProject vsProject = (VSLangProj.VSProject)project.Object;
1981 foreach(Reference r in vsProject.References)
1983 if(Array.BinarySearch(Util.getSilverlightNames(), r.Name, StringComparer.CurrentCultureIgnoreCase) < 0)
1985 continue;
1988 components.Add(r.Name);
1990 return components;
1993 public static ComponentList getIceDotNetComponents(Project project)
1995 ComponentList components = new ComponentList();
1996 if(project == null)
1998 return components;
2001 string[] componentNames = null;
2002 if(Util.isCSharpSmartDeviceProject(project) || Util.isVBSmartDeviceProject(project))
2004 componentNames = getDotNetCompactNames();
2006 else
2008 componentNames = getDotNetNames();
2010 VSLangProj.VSProject vsProject = (VSLangProj.VSProject)project.Object;
2011 foreach(Reference r in vsProject.References)
2013 if(Array.BinarySearch(componentNames, r.Name, StringComparer.CurrentCultureIgnoreCase) < 0)
2015 continue;
2018 components.Add(r.Name);
2020 return components;
2023 public static bool addIceCppConfigurations(Project project)
2025 if(!isCppProject(project))
2027 return false;
2030 VCProject vcProject = (VCProject)project.Object;
2031 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
2032 bool changed = false;
2034 Util.addIcePropertySheet(project);
2036 foreach(VCConfiguration conf in configurations)
2038 if(addIceCppConfiguration(project, conf))
2040 changed = true;
2043 return changed;
2046 public static bool addIceCppConfiguration(Project project, VCConfiguration conf)
2048 if(!isCppProject(project))
2050 return false;
2053 bool x64 = false;
2055 if(conf == null || String.IsNullOrEmpty(conf.Name))
2057 return false;
2061 x64 = false;
2062 VCPlatform platform = (VCPlatform)conf.Platform;
2063 if(platform == null || String.IsNullOrEmpty(platform.Name))
2065 return false;
2068 if(platform.Name.Equals("x64", StringComparison.CurrentCultureIgnoreCase) ||
2069 platform.Name.Equals("Itanium", StringComparison.CurrentCultureIgnoreCase))
2071 x64 = true;
2073 VCCLCompilerTool compilerTool =
2074 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
2075 VCLinkerTool linkerTool = (VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool"));
2077 Util.addIceCppEnvironment((VCDebugSettings)conf.DebugSettings, project, x64);
2078 bool libChanged = Util.addIceCppLibraryDir(linkerTool, project, x64);
2079 bool includesChanged = Util.addCppIncludes(compilerTool, project);
2081 return libChanged | includesChanged;
2084 public static void removeIceCppConfigurations(Project project)
2086 if(!isCppProject(project))
2088 return;
2091 VCProject vcProject = (VCProject)project.Object;
2092 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
2093 foreach(VCConfiguration conf in configurations)
2095 if(conf == null)
2097 continue;
2100 VCCLCompilerTool compilerTool =
2101 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
2102 VCLinkerTool linkerTool = (VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool"));
2105 Util.removeIceCppEnvironment((VCDebugSettings)conf.DebugSettings, "$(IceHome)");
2106 Util.removeIceCppLibraryDir(linkerTool, "$(IceHome)");
2107 Util.removeCppIncludes(compilerTool, "$(IceHome)", Util.getProjectOutputDirRaw(project));
2108 Util.removeIcePropertySheet(conf);
2110 Util.removeIceCppLibs(project);
2113 public static void addIceCppLibs(Project project, ComponentList components)
2115 if(!isCppProject(project))
2117 return;
2120 VCProject vcProject = (VCProject)project.Object;
2121 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
2123 foreach(VCConfiguration conf in configurations)
2125 if(conf == null)
2127 continue;
2129 VCCLCompilerTool compilerTool =
2130 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
2131 VCLinkerTool linkerTool = (VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool"));
2133 if(compilerTool == null || linkerTool == null)
2135 continue;
2138 bool debug = isDebug(compilerTool.RuntimeLibrary);
2140 foreach(string component in components)
2142 if(String.IsNullOrEmpty(component))
2144 continue;
2146 Util.addCppLib(linkerTool, component, debug);
2151 public static ComponentList removeIceCppLibs(Project project)
2153 return Util.removeIceCppLibs(project, new ComponentList(Util.getCppNames()));
2156 public static ComponentList removeIceCppLibs(Project project, ComponentList components)
2158 ComponentList removed = new ComponentList();
2159 if(!isCppProject(project))
2161 return removed;
2164 VCProject vcProject = (VCProject)project.Object;
2165 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
2167 foreach(VCConfiguration conf in configurations)
2169 if(conf == null)
2171 continue;
2173 VCCLCompilerTool compilerTool =
2174 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
2175 VCLinkerTool linkerTool = (VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool"));
2177 if(compilerTool == null || linkerTool == null)
2179 continue;
2182 bool debug = false;
2183 if(!String.IsNullOrEmpty(compilerTool.PreprocessorDefinitions))
2185 debug = (compilerTool.PreprocessorDefinitions.Contains("DEBUG") &&
2186 !compilerTool.PreprocessorDefinitions.Contains("NDEBUG"));
2188 if(!debug)
2190 debug = conf.Name.Contains("Debug");
2193 foreach(string s in components)
2195 if(String.IsNullOrEmpty(s))
2197 continue;
2200 if(Util.removeCppLib(linkerTool, s, debug) && !removed.Contains(s))
2202 removed.Add(s);
2206 return removed;
2210 // Return true if the .NET reference that corresponds to the Ice component
2211 // is present in the given project.
2213 public static bool hasDotNetReference(Project project, string component)
2215 bool found = false;
2216 foreach(Reference r in ((VSProject)project.Object).References)
2218 if(r.Name.Equals(component, StringComparison.OrdinalIgnoreCase))
2220 found = true;
2221 break;
2224 return found;
2228 // Return true if at least one of the C++ project configurations contains
2229 // the library corresponding to the given component.
2231 public static bool hasIceCppLib(Project project, string component)
2233 if(!isCppProject(project))
2235 return false;
2238 if(Array.BinarySearch(Util.getCppNames(), component, StringComparer.CurrentCultureIgnoreCase) < 0)
2240 return false;
2243 VCProject vcProject = (VCProject)project.Object;
2244 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
2245 bool found = false;
2247 foreach(VCConfiguration conf in configurations)
2249 if(conf == null)
2251 continue;
2254 VCCLCompilerTool compilerTool =
2255 (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
2256 VCLinkerTool linkerTool = (VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool"));
2258 if(compilerTool == null || linkerTool == null)
2260 continue;
2263 bool debug = false;
2264 if(!String.IsNullOrEmpty(compilerTool.PreprocessorDefinitions))
2266 debug = (compilerTool.PreprocessorDefinitions.Contains("DEBUG") &&
2267 !compilerTool.PreprocessorDefinitions.Contains("NDEBUG"));
2269 if(!debug)
2271 debug = conf.Name.Contains("Debug");
2274 string libName = component;
2275 if(debug)
2277 libName += "d";
2279 libName += ".lib";
2281 string additionalDependencies = linkerTool.AdditionalDependencies;
2282 if(String.IsNullOrEmpty(additionalDependencies))
2284 continue;
2287 ComponentList components = new ComponentList(additionalDependencies.Split(' '));
2288 if(components.Contains(libName))
2290 found = true;
2291 break;
2294 return found;
2297 public static DTE getCurrentDTE()
2299 return Connect.getCurrentDTE();
2302 public static string expandEnvironmentVars(string s)
2304 if(String.IsNullOrEmpty(s))
2306 return s;
2308 string result = s;
2309 int beg = 0;
2310 int end = 0;
2311 while(beg < result.Length &&
2312 (beg = result.IndexOf("$(", beg, StringComparison.Ordinal)) != -1 &&
2313 (end = result.IndexOf(")", beg, StringComparison.Ordinal)) != -1)
2315 string variable = result.Substring(beg + "$(".Length, end - (beg + "$(".Length));
2316 string value = System.Environment.GetEnvironmentVariable(variable);
2317 if(value == null)
2319 // Skip undefined vars.
2320 beg += "$(".Length + variable.Length + ")".Length;
2321 continue;
2323 result = result.Replace("$(" + variable + ")", value);
2324 beg += value.Length;
2326 return result;
2329 public static bool containsEnvironmentVars(string s)
2331 if(String.IsNullOrEmpty(s))
2333 return false;
2335 return s.Contains("$(");
2338 public static string quote(string arg)
2340 if(String.IsNullOrEmpty(arg))
2342 return "\"\"";
2344 return "\"" + arg + "\"";
2347 public static void verifyProjectSettings(Project project)
2349 if (isCppProject(project))
2351 addIceCppConfigurations(project); ;
2353 else
2355 string iceHome = getIceHome();
2356 string binDir = getCsBinDir(project);
2357 ComponentList components = Util.getIceDotNetComponents(project);
2358 String version = Builder.getSliceCompilerVersion(project, Util.slice2cs);
2360 string[] tokens = version.Split('.');
2362 // Add patch version 0 if there isn't one
2364 if(tokens.Length == 3)
2366 version += ".0";
2369 foreach(string component in components)
2371 if (String.IsNullOrEmpty(component))
2373 continue;
2376 string reference = iceHome + binDir + component + ".dll";
2379 // If Ice components are not from the current Ice home binary
2380 // directory, we update the references to use the new value of
2381 // Ice home.
2383 bool development = developmentMode(project);
2384 foreach(Reference r in ((VSProject)project.Object).References)
2386 if(r.Name.Equals(component, StringComparison.OrdinalIgnoreCase))
2388 if(!r.Path.Equals(reference) ||
2389 !r.Version.Equals(version))
2391 bool copyLocal = getCopyLocal(project, component);
2392 Util.removeDotNetReference(project, component);
2394 Util.addDotNetReference(project, component, iceHome, development);
2395 setCopyLocal(project, component, copyLocal);
2397 break;
2404 public static bool addBuilderToProject(Project project, ComponentList components)
2406 Builder builder = Connect.getBuilder();
2407 if(builder == null || project == null)
2409 return false;
2412 if(Util.isSliceBuilderEnabled(project))
2414 return false; // Already enabled.
2417 builder.addBuilderToProject(project, components);
2418 return true;
2421 public static bool removeBuilderFromProject(Project project, ComponentList components)
2423 Builder builder = Connect.getBuilder();
2424 if(builder == null || project == null)
2426 return false;
2429 if(!Util.isSliceBuilderEnabled(project))
2431 return false; // Already disabled.
2434 builder.removeBuilderFromProject(project, components);
2435 return true;
2438 public static void cleanProject(Project project, bool remove)
2440 Builder builder = Connect.getBuilder();
2441 builder.cleanProject(project, remove);
2444 public static void rebuildProject(Project project)
2446 Builder builder = Connect.getBuilder();
2447 builder.cleanProject(project, false);
2448 builder.buildProject(project, true, vsBuildScope.vsBuildScopeProject);
2451 public static int getVerboseLevel(Project p)
2453 int verboseLevel = (int)Util.msgLevel.msgInfo;
2454 if(p != null)
2458 verboseLevel = Int32.Parse(Util.getProjectProperty(p, Util.PropertyVerboseLevel),
2459 CultureInfo.InvariantCulture);
2461 catch(ArgumentNullException)
2464 catch(FormatException)
2467 catch(OverflowException)
2471 return verboseLevel;
2474 public static void write(Project p, Util.msgLevel msgLevel, string message)
2476 Builder builder = Connect.getBuilder();
2477 if(builder == null)
2479 return;
2482 int verboseLevel = getVerboseLevel(p);
2484 if((int)msgLevel <= verboseLevel)
2486 if(!builder.commandLine)
2488 OutputWindowPane pane = builder.buildOutput();
2489 if(pane == null)
2491 return;
2493 pane.Activate();
2494 pane.OutputString(message);
2496 else
2498 System.Console.Write(message);
2504 // Get the assembly name of a .NET project
2506 public static string assemblyName(Project project)
2508 if(project == null)
2510 return "";
2512 if(!isCSharpProject(project) && !isVBProject(project))
2514 return "";
2517 Property assemblyName = project.Properties.Item("AssemblyName");
2519 if(assemblyName.Value == null)
2521 return "";
2523 return assemblyName.Value.ToString();
2527 // Check if the Visual Studio hosting process is enabled in any of
2528 // the project configurations.
2530 public static bool useVSHostingProcess(Project p)
2532 bool enabled = false;
2533 foreach(Configuration config in p.ConfigurationManager)
2535 if(config.Properties == null)
2537 continue;
2539 Property property = config.Properties.Item("UseVSHostingProcess");
2540 if(property.Value.ToString().Equals(true.ToString(), StringComparison.CurrentCultureIgnoreCase))
2542 enabled = true;
2543 break;
2546 return enabled;
2550 // Enable/Disable the Visual Studio hosting process. We use this
2551 // to force Visual Studio to restart the hosting process, which is
2552 // necessary for the process to run with updated environment variables.
2554 public static void setVsHostingProcess(Project p, bool value)
2556 foreach(Configuration config in p.ConfigurationManager)
2558 if(config == null)
2560 continue;
2563 if(config.Properties == null)
2565 continue;
2568 Property property = config.Properties.Item("UseVSHostingProcess");
2569 if(property == null)
2571 continue;
2574 if(property.Value != null)
2576 if(property.Value.ToString().Equals(value.ToString(), StringComparison.CurrentCultureIgnoreCase))
2578 continue;
2581 property.Value = value;
2586 // Check if the .NET development mode is enabled in the application config that resides in
2587 // the file <applicationName>.exe.config.
2589 public static bool developmentMode(Project project)
2591 string configPath =
2592 Path.Combine(Path.GetDirectoryName(project.FileName), assemblyName(project) + ".exe.config");
2593 if(!File.Exists(configPath))
2595 return false;
2598 System.Xml.XmlDocument dom = new System.Xml.XmlDocument();
2602 dom.Load(configPath);
2603 System.Xml.XmlNodeList nodes = dom.SelectNodes("/configuration/runtime/developmentMode");
2604 if(nodes.Count <= 0)
2606 return false;
2608 System.Xml.XmlNode node = nodes[0];
2610 System.Xml.XmlAttribute attribute = node.Attributes["developerInstallation"];
2612 if(attribute == null)
2614 return false;
2617 if(String.IsNullOrEmpty(attribute.Value))
2619 return false;
2621 return attribute.Value.Equals("true", StringComparison.CurrentCultureIgnoreCase);
2623 catch(System.Xml.XmlException)
2625 return false; // There was an error parsing the XML
2629 public static bool parseSlice2slOptions(string args, bool showWarning, ref Options opts)
2633 opts = null;
2635 if(String.IsNullOrEmpty(args))
2637 return true; //No options to parse
2640 opts = new Options();
2641 opts.addOpt("h", "help");
2642 opts.addOpt("v", "version");
2643 opts.addOpt("D", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2644 opts.addOpt("U", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2645 opts.addOpt("I", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2646 opts.addOpt("E");
2647 opts.addOpt("", "output-dir", Options.ArgType.NeedArg);
2648 opts.addOpt("", "depend");
2649 opts.addOpt("d", "debug");
2650 opts.addOpt("", "ice");
2651 opts.addOpt("", "case-sensitive");
2653 opts.parse(Options.split(args));
2655 checkInvalidOptions(opts);
2657 return true;
2659 catch(BadOptionException ex)
2661 if(showWarning)
2663 showExtraOptionsWarning(ex);
2665 return false;
2669 public static bool parseSlice2csOptions(string args, bool showWarning, ref Options opts)
2673 opts = null;
2675 if(String.IsNullOrEmpty(args))
2677 return true; //No options to parse
2680 opts = new Options();
2681 opts.addOpt("h", "help");
2682 opts.addOpt("v", "version");
2683 opts.addOpt("D", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2684 opts.addOpt("U", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2685 opts.addOpt("I", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2686 opts.addOpt("E");
2687 opts.addOpt("", "output-dir", Options.ArgType.NeedArg);
2688 opts.addOpt("", "tie");
2689 opts.addOpt("", "impl");
2690 opts.addOpt("", "impl-tie");
2691 opts.addOpt("", "depend");
2692 opts.addOpt("d", "debug");
2693 opts.addOpt("", "ice");
2694 opts.addOpt("", "underscore");
2695 opts.addOpt("", "checksum");
2696 opts.addOpt("", "stream");
2698 opts.parse(Options.split(args));
2700 checkInvalidOptions(opts);
2702 return true;
2704 catch(BadOptionException ex)
2706 if(showWarning)
2708 showExtraOptionsWarning(ex);
2710 return false;
2714 public static bool parseSlice2cppOptions(string args, bool showWarning, ref Options opts,
2715 ref string headerExt, ref string sourceExt)
2719 opts = null;
2720 headerExt = "";
2721 sourceExt = "";
2723 if(String.IsNullOrEmpty(args))
2725 return true; //No options to parse
2728 opts = new Options();
2729 opts.addOpt("h", "help");
2730 opts.addOpt("v", "version");
2731 opts.addOpt("", "header-ext", Options.ArgType.NeedArg, "h");
2732 opts.addOpt("", "source-ext", Options.ArgType.NeedArg, "cpp");
2733 opts.addOpt("", "add-header", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2734 opts.addOpt("D", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2735 opts.addOpt("U", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2736 opts.addOpt("I", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
2737 opts.addOpt("E");
2738 opts.addOpt("", "include-dir", Options.ArgType.NeedArg);
2739 opts.addOpt("", "output-dir", Options.ArgType.NeedArg);
2740 opts.addOpt("", "dll-export", Options.ArgType.NeedArg);
2741 opts.addOpt("", "impl");
2742 opts.addOpt("", "depend");
2743 opts.addOpt("d", "debug");
2744 opts.addOpt("", "ice");
2745 opts.addOpt("", "underscore");
2746 opts.addOpt("", "checksum");
2747 opts.addOpt("", "stream");
2749 opts.parse(Options.split(args));
2751 checkInvalidOptions(opts);
2753 string hExt = opts.optArg("header-ext");
2754 string cppExt = opts.optArg("source-ext");
2756 if(Util.containsEnvironmentVars(hExt) ||
2757 Util.containsEnvironmentVars(cppExt))
2759 throw new BadOptionException(
2760 "You cannot use environment variables in `--header-ext' or `--source-ext' options.");
2762 headerExt = hExt;
2763 sourceExt = cppExt;
2765 if(opts.isSet("dll-export"))
2767 throw new BadOptionException(
2768 "Use the `DLL Export Symbol' text box below to set the --dll-export option\n" +
2769 "instead of the `Extra Compiler Options' text box.");
2772 return true;
2774 catch(BadOptionException ex)
2776 if(showWarning)
2778 showExtraOptionsWarning(ex);
2780 return false;
2785 // Check for common options that must not appear in Extra Options textbox.
2787 private static void checkInvalidOptions(Options opts)
2789 if(opts.isSet("output-dir"))
2791 throw new BadOptionException(
2792 "Use the `Output Dir' text box above to set `--output-dir' option\n" +
2793 "instead of the `Extra Compiler Options' text box.");
2796 if(opts.isSet("depend"))
2798 throw new BadOptionException("Don't use `--depend' option in `Extra Options' text box.");
2801 if(opts.isSet("help"))
2803 throw new BadOptionException("Don't use `--help' or `-h' option in `Extra Options' text box.");
2806 if(opts.isSet("version"))
2808 throw new BadOptionException("Don't use `--version' or `-v' option in `Extra Options' text box.");
2812 private static void showRunTimeLibraryWarning(Project p)
2814 string err = "Run Time library not supported with Ice, Ice requires /MD or /MDd Run Time Library.";
2815 MessageBox.Show(err, "Ice Visual Studio Add-in", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1,
2816 (MessageBoxOptions)0);
2818 Util.write(p, msgLevel.msgError, err);
2821 private static void showExtraOptionsWarning(BadOptionException ex)
2823 MessageBox.Show("Extra Options field contains some errors:\n" +
2824 ex.reason,
2825 "Ice Visual Studio Add-in", MessageBoxButtons.OK,
2826 MessageBoxIcon.Error,
2827 MessageBoxDefaultButton.Button1,
2828 (MessageBoxOptions)0);
2832 public static void unexpectedExceptionWarning(Exception ex)
2836 Builder builder = Connect.getBuilder();
2837 if(!builder.commandLine)
2839 MessageBox.Show("The Ice Visual Studio Add-in has raised an unexpected exception:\n" +
2840 ex.ToString(),
2841 "Ice Visual Studio Add-in", MessageBoxButtons.OK,
2842 MessageBoxIcon.Error,
2843 MessageBoxDefaultButton.Button1,
2844 (MessageBoxOptions)0);
2847 catch(Exception)
2853 Util.write(null, Util.msgLevel.msgError, ex.ToString() + "\n");
2855 catch(Exception)
2860 public static string getHeaderExt(Project p)
2862 String extension = getProjectProperty(p, Util.PropertyIceHeaderExt);
2863 if(String.IsNullOrEmpty(extension))
2865 extension = "h";
2867 return extension;
2870 public static string getSourceExt(Project p)
2872 String extension = getProjectProperty(p, Util.PropertyIceSourceExt);
2873 if(String.IsNullOrEmpty(extension))
2875 extension = "cpp";
2877 return extension;
2881 // Warn the user about unsaved changes. Returns true if the user
2882 // wants to discard changes, otherwise returns false.
2884 public static bool warnUnsavedChanges(IWin32Window owner)
2886 if(MessageBox.Show(owner, "Are you sure you want to discard all changes?",
2887 "Ice Visual Studio Add-in", MessageBoxButtons.YesNo,
2888 MessageBoxIcon.Question, MessageBoxDefaultButton.Button1,
2889 (MessageBoxOptions)0) == DialogResult.Yes)
2891 return true;
2893 return false;
2896 public static List<ProjectItem> clone(ProjectItems items)
2898 List<ProjectItem> list = new List<ProjectItem>();
2899 foreach(ProjectItem i in items)
2901 list.Add(i);
2903 return list;
2906 public static List<Project> getProjects(Solution solution)
2908 List<Project> projects = new List<Project>();
2909 foreach(Project p in solution.Projects)
2911 getProjects(solution, p, ref projects);
2913 return projects;
2916 public static void getProjects(Solution solution, Project project, ref List<Project> projects)
2918 if(project.Kind == EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder)
2920 foreach(ProjectItem item in project.ProjectItems)
2922 Project p = item.Object as Project;
2923 if(p == null)
2925 continue;
2927 getProjects(solution, p, ref projects);
2930 if(projects.Find(
2931 delegate(Project p)
2933 return project.UniqueName.Equals(p.UniqueName);
2934 }) == null)
2936 projects.Add(project);
2941 // Rerturn a list of projects with match the build order
2942 // of the solution.
2944 public static List<Project> buildOrder(Solution solution)
2946 List<Project> projects = new List<Project>();
2947 foreach(Project p in solution.Projects)
2949 buildOrder(solution, p, ref projects);
2951 return projects;
2956 // This method helps to build the list of projects with the
2957 // right build order.
2959 public static void buildOrder(Solution solution, Project project, ref List<Project> projects)
2961 if(project.Kind == EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder)
2963 foreach(ProjectItem item in project.ProjectItems)
2965 Project p = item.Object as Project;
2966 if(p == null)
2968 continue;
2970 buildOrder(solution, p, ref projects);
2973 BuildDependencies dependencies = solution.SolutionBuild.BuildDependencies;
2974 for(int i = 0; i < dependencies.Count; ++i)
2976 BuildDependency dp = dependencies.Item(i + 1);
2977 if(dp.Project.Equals(project))
2979 System.Array requiredProjects = dp.RequiredProjects as System.Array;
2980 if(requiredProjects == null)
2982 continue;
2984 foreach(Project p in requiredProjects)
2986 Util.buildOrder(solution, p, ref projects);
2990 if(projects.Find(
2991 delegate(Project p)
2993 return project.UniqueName.Equals(p.UniqueName);
2994 }) == null)
2996 projects.Add(project);
3000 public static List<Project> solutionFolderProjects(Project project)
3002 List<Project> projects = new List<Project>();
3003 if(!project.Kind.Equals(EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder))
3005 return projects;
3007 solutionFolderProjects(project, ref projects);
3008 return projects;
3011 public static void solutionFolderProjects(Project project, ref List<Project> projects)
3013 if(project.Kind.Equals(EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder))
3015 foreach(ProjectItem item in project.ProjectItems)
3017 Project p = item.Object as Project;
3018 if(p == null)
3020 continue;
3022 solutionFolderProjects(p, ref projects);
3025 else
3027 if(!projects.Contains(project))
3029 projects.Add(project);
3035 // This methods refresh the solution explorer if the command
3036 // is available.
3038 public static void solutionExplorerRefresh()
3040 if(_refreshCommand != null && _refreshCommand.IsAvailable)
3042 DTE dte = getCurrentDTE();
3043 object objIn = null;
3044 object objOut = null;
3045 dte.Commands.Raise(refreshCommandGUID, refreshCommandID, ref objIn, ref objOut);
3049 public static void setRefreshCommand(Command command)
3051 _refreshCommand = command;
3054 static public bool hasProjecType(Project project, string type)
3056 ComponentList types = new ComponentList(getProjectTypeGuids(project), ';');
3057 return types.Contains(type);
3060 static public string getProjectTypeGuids(Project proj)
3062 string guids = "";
3063 Microsoft.VisualStudio.Shell.Interop.IVsHierarchy hierarchy = null;
3064 Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject aggregatableProject = null;
3065 IVsSolution solution = getIVsSolution();
3067 int result = solution.GetProjectOfUniqueName(proj.UniqueName, out hierarchy);
3069 if(result == 0)
3071 aggregatableProject = (Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject)hierarchy;
3072 result = aggregatableProject.GetAggregateProjectTypeGuids(out guids);
3074 return guids;
3077 static private IVsSolution getIVsSolution()
3080 Guid serviceGuid = typeof(SVsSolution).GUID;
3081 Guid interfaceGuid = typeof(IVsSolution).GUID;
3082 IntPtr ppObject;
3084 Microsoft.VisualStudio.OLE.Interop.IServiceProvider serviceProvider =
3085 (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)getCurrentDTE();
3087 if(ErrorHandler.Failed(serviceProvider.QueryService(ref serviceGuid, ref interfaceGuid, out ppObject)))
3089 return null;
3092 IVsSolution service = null;
3093 if(!ppObject.Equals(IntPtr.Zero))
3095 service = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(ppObject) as IVsSolution;
3096 System.Runtime.InteropServices.Marshal.Release(ppObject);
3099 return service;
3103 // Check if we are using a debug run-time library.
3105 static public bool isDebug(runtimeLibraryOption rt)
3107 return rt == runtimeLibraryOption.rtMultiThreadedDebug || rt == runtimeLibraryOption.rtMultiThreadedDebugDLL;
3111 // Check if the run time library is supported with Ice projects
3113 static public bool checkCppRunTimeLibrary(Project p, runtimeLibraryOption rt)
3115 return rt == runtimeLibraryOption.rtMultiThreadedDebugDLL || rt == runtimeLibraryOption.rtMultiThreadedDLL;
3118 static public bool checkCppRunTimeLibrary(Builder builder, Project project, VCCLCompilerTool compilerTool,
3119 VCLinkerTool linkerTool)
3122 // Check the project run time library for the active configuration.
3124 if(!Util.checkCppRunTimeLibrary(project, compilerTool.RuntimeLibrary))
3126 builder.addError(project, "", TaskErrorCategory.Error, 0, 0,
3127 "The selected C++ Runtime Library is not supported by Ice; Ice requires /MD or /MDd.");
3128 return false;
3132 // Ensure that linker settings match the Runtime Library settings.
3134 ComponentList components = Util.getIceCppComponents(project);
3135 bool debug = Util.isDebug(compilerTool.RuntimeLibrary);
3136 string additionalDependencies = linkerTool.AdditionalDependencies;
3139 // For each component we need to check that the correct
3140 // library version (debug/release) is used.
3142 foreach(string c in components)
3144 string debugName = c + "d.lib";
3145 string releaseName = c + ".lib";
3147 if((debug && additionalDependencies.Contains(debugName)) ||
3148 (!debug && additionalDependencies.Contains(releaseName)))
3150 continue;
3153 if(debug)
3155 if(additionalDependencies.Contains(releaseName))
3157 additionalDependencies = additionalDependencies.Replace(releaseName, debugName);
3159 else
3161 if(!String.IsNullOrEmpty(additionalDependencies) &&
3162 !additionalDependencies.TrimEnd().EndsWith(";"))
3164 additionalDependencies += ";";
3166 additionalDependencies += debugName;
3169 else
3171 if(additionalDependencies.Contains(debugName))
3173 additionalDependencies = additionalDependencies.Replace(debugName, releaseName);
3175 else
3177 if(!String.IsNullOrEmpty(additionalDependencies) &&
3178 !additionalDependencies.TrimEnd().EndsWith(";"))
3180 additionalDependencies += ";";
3182 additionalDependencies += releaseName;
3188 // If the linker settings has changed we update it.
3190 if(!additionalDependencies.Equals(linkerTool.AdditionalDependencies))
3192 linkerTool.AdditionalDependencies = additionalDependencies;
3194 return true;
3197 static public VCConfiguration getActiveVCConfiguration(Project project)
3199 if(!Util.isCppProject(project))
3201 return null;
3203 ConfigurationManager configManager = project.ConfigurationManager;
3204 if(configManager == null)
3206 return null;
3209 Configuration activeConfig;
3212 activeConfig = (Configuration)configManager.ActiveConfiguration;
3214 catch(COMException)
3216 return null;
3219 if(activeConfig == null)
3221 return null;
3224 VCProject vcProject = (VCProject)project.Object;
3225 IVCCollection configurations = (IVCCollection)vcProject.Configurations;
3226 VCConfiguration configuration = null;
3227 foreach(VCConfiguration c in configurations)
3229 if(c.Name != (activeConfig.ConfigurationName + "|" + activeConfig.PlatformName))
3231 continue;
3233 configuration = c;
3234 break;
3236 return configuration;
3239 public static string projectFullName(Project p)
3241 if(p.ParentProjectItem != null &&
3242 p.ParentProjectItem.ContainingProject != null)
3244 return projectFullName(p.ParentProjectItem.ContainingProject) + "/" + p.Name;
3246 return p.Name;
3249 public static string getTraceProjectName(Project project)
3251 string fullName = projectFullName(project);
3252 if(fullName.Equals(project.Name))
3254 return fullName;
3256 return project.Name + " (" + fullName + ")";
3259 private static Command _refreshCommand;
3260 public const string refreshCommandGUID = "{1496A755-94DE-11D0-8C3F-00C04FC2AAE2}";
3261 public const string vsSmartDeviceCSharp = "{4D628B5B-2FBC-4AA6-8C16-197242AEB884}";
3262 public const string vsSmartDeviceVB = "{68B1623D-7FB9-47D8-8664-7ECEA3297D4F}";
3264 public const int refreshCommandID = 222;