PageRenderTime 37ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/vsaddin/src/Util.cs

https://bitbucket.org/cleto/zeroc-ice-package
C# | 3577 lines | 3473 code | 83 blank | 21 comment | 85 complexity | c342b39434833a35c51facdd11f5ee7f MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, GPL-2.0, BSD-3-Clause
  1. // **********************************************************************
  2. //
  3. // Copyright (c) 2003-2013 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. // **********************************************************************
  9. using System;
  10. using System.Text;
  11. using System.Collections.Generic;
  12. using System.ComponentModel;
  13. using EnvDTE;
  14. using System.Windows.Forms;
  15. using System.Runtime.InteropServices;
  16. using System.IO;
  17. using System.Diagnostics;
  18. using Extensibility;
  19. using EnvDTE80;
  20. using Microsoft.VisualStudio;
  21. using Microsoft.VisualStudio.CommandBars;
  22. using Microsoft.VisualStudio.VCProjectEngine;
  23. using Microsoft.VisualStudio.VCProject;
  24. using Microsoft.VisualStudio.Shell;
  25. using Microsoft.VisualStudio.Shell.Interop;
  26. using System.Resources;
  27. using System.Reflection;
  28. using VSLangProj;
  29. using System.Globalization;
  30. using System.Collections;
  31. using System.Runtime.InteropServices.ComTypes;
  32. using Microsoft.CSharp;
  33. using System.Xml;
  34. namespace Ice.VisualStudio
  35. {
  36. public class InitializationException : System.Exception
  37. {
  38. public InitializationException(string message) : base(message)
  39. {
  40. }
  41. }
  42. public enum CPUType
  43. {
  44. x86CPUType,
  45. x64CPUType,
  46. ARMCPUType
  47. }
  48. public interface LinkerAdapter
  49. {
  50. String AdditionalDependencies
  51. {
  52. get;
  53. set;
  54. }
  55. String AdditionalLibraryDirectories
  56. {
  57. get;
  58. set;
  59. }
  60. }
  61. public class DynamicLinkerAdapter : LinkerAdapter
  62. {
  63. public DynamicLinkerAdapter(VCLinkerTool linkerTool)
  64. {
  65. _linkerTool = linkerTool;
  66. }
  67. public String AdditionalDependencies
  68. {
  69. get
  70. {
  71. return _linkerTool.AdditionalDependencies;
  72. }
  73. set
  74. {
  75. _linkerTool.AdditionalDependencies = value;
  76. }
  77. }
  78. public String AdditionalLibraryDirectories
  79. {
  80. get
  81. {
  82. return _linkerTool.AdditionalLibraryDirectories;
  83. }
  84. set
  85. {
  86. _linkerTool.AdditionalLibraryDirectories = value;
  87. }
  88. }
  89. private VCLinkerTool _linkerTool;
  90. }
  91. public class StaticLinkerAdapter : LinkerAdapter
  92. {
  93. public StaticLinkerAdapter(VCLibrarianTool librarianTool)
  94. {
  95. _librarianTool = librarianTool;
  96. }
  97. public String AdditionalDependencies
  98. {
  99. get
  100. {
  101. return "";
  102. }
  103. set
  104. {
  105. }
  106. }
  107. public String AdditionalLibraryDirectories
  108. {
  109. get
  110. {
  111. return "";
  112. }
  113. set
  114. {
  115. }
  116. }
  117. private VCLibrarianTool _librarianTool;
  118. }
  119. public class ComponentList : List<string>
  120. {
  121. public ComponentList()
  122. {
  123. }
  124. public ComponentList(string[] values)
  125. {
  126. foreach(string s in values)
  127. {
  128. Add(s);
  129. }
  130. }
  131. public ComponentList(string value)
  132. {
  133. if(value == null)
  134. {
  135. value = "";
  136. }
  137. init(value, ';');
  138. }
  139. public ComponentList(string value, char separator)
  140. {
  141. init(value, separator);
  142. }
  143. public new void Add(string value)
  144. {
  145. value = value.Trim();
  146. if(String.IsNullOrEmpty(value))
  147. {
  148. return;
  149. }
  150. if(!base.Contains(value))
  151. {
  152. base.Add(value);
  153. }
  154. }
  155. public new bool Contains(string value)
  156. {
  157. string v = base.Find(delegate(string s)
  158. {
  159. return s.Equals(value.Trim(), StringComparison.CurrentCultureIgnoreCase);
  160. });
  161. return v != null;
  162. }
  163. public new bool Remove(string value)
  164. {
  165. value = value.Trim();
  166. //
  167. // To do the remove case insensitive, first find the value
  168. // doing case insensitive comparison and then remove that.
  169. //
  170. string v = base.Find(delegate(string s)
  171. {
  172. return s.Equals(value.Trim(), StringComparison.CurrentCultureIgnoreCase);
  173. });
  174. if(v != null)
  175. {
  176. return base.Remove(v);
  177. }
  178. return false;
  179. }
  180. private void init(string value, char separator)
  181. {
  182. Array items = value.Split(separator);
  183. foreach(string s in items)
  184. {
  185. Add(s);
  186. }
  187. }
  188. public override string ToString()
  189. {
  190. return ToString(';');
  191. }
  192. public string ToString(char separator)
  193. {
  194. if(this.Count == 0)
  195. {
  196. return "";
  197. }
  198. StringBuilder sb = new StringBuilder();
  199. for(int cont = 0; cont < this.Count; ++cont)
  200. {
  201. sb.Append(this[cont]);
  202. if(cont < this.Count - 1)
  203. {
  204. sb.Append(separator);
  205. }
  206. }
  207. return sb.ToString();
  208. }
  209. public bool Equal(ComponentList other)
  210. {
  211. if(this.Count != other.Count)
  212. {
  213. return false;
  214. }
  215. bool equal = true;
  216. for(int i = 0; i < this.Count; ++i)
  217. {
  218. string val1 = this[i];
  219. string val2 = other[i];
  220. if(val1 == null && val2 == null)
  221. {
  222. continue;
  223. }
  224. if(val1 == null || val2 == null)
  225. {
  226. equal = false;
  227. break;
  228. }
  229. if(!val1.Equals(val2, StringComparison.CurrentCultureIgnoreCase))
  230. {
  231. equal = false;
  232. break;
  233. }
  234. }
  235. return equal;
  236. }
  237. }
  238. public class IncludePathList : ComponentList
  239. {
  240. public IncludePathList()
  241. : base()
  242. {
  243. }
  244. public IncludePathList(string[] values)
  245. : base(values)
  246. {
  247. }
  248. public IncludePathList(string value)
  249. : base(value, '|')
  250. {
  251. }
  252. public override string ToString()
  253. {
  254. return base.ToString('|');
  255. }
  256. public bool Contains(Project project, string value)
  257. {
  258. string path = Util.absolutePath(project, value);
  259. string found = base.Find(delegate(string s)
  260. {
  261. string other = Util.absolutePath(project, s);
  262. return path.Equals(other, StringComparison.CurrentCultureIgnoreCase);
  263. });
  264. return found != null;
  265. }
  266. }
  267. public static class Util
  268. {
  269. public enum msgLevel{ msgError, msgInfo, msgDebug };
  270. public static string MajorVersion
  271. {
  272. get
  273. {
  274. if (_majorVersion == null)
  275. {
  276. string[] tokens = Assembly.GetExecutingAssembly().GetName().Version.ToString().Split('.');
  277. Debug.Assert(tokens.Length > 1);
  278. _majorVersion = tokens[0];
  279. }
  280. return _majorVersion;
  281. }
  282. }
  283. private static string _majorVersion = null;
  284. public static string MinorVersion
  285. {
  286. get
  287. {
  288. if (_minorVersion == null)
  289. {
  290. string[] tokens = Assembly.GetExecutingAssembly().GetName().Version.ToString().Split('.');
  291. Debug.Assert(tokens.Length > 1);
  292. _minorVersion = tokens[1];
  293. }
  294. return _minorVersion;
  295. }
  296. }
  297. private static string _minorVersion = null;
  298. public const string ProjectVersion = "1";
  299. public const string slice2cs = "slice2cs.exe";
  300. public const string slice2cpp = "slice2cpp.exe";
  301. //
  302. // Property names used to persist project configuration.
  303. //
  304. public const string PropertyIce = "ZerocIce_Enabled";
  305. public const string PropertyIceOutputDir = "ZerocIce_OutputDir";
  306. public const string PropertyIceHeaderExt = "ZerocIce_HeaderExt";
  307. public const string PropertyIceSourceExt = "ZerocIce_SourceExt";
  308. public const string PropertyIceComponents = "ZerocIce_Components";
  309. public const string PropertyIceExtraOptions = "ZerocIce_ExtraOptions";
  310. public const string PropertyIceIncludePath = "ZerocIce_IncludePath";
  311. public const string PropertyIceStreaming = "ZerocIce_Streaming";
  312. public const string PropertyIceChecksum = "ZerocIce_Checksum";
  313. public const string PropertyIceTie = "ZerocIce_Tie";
  314. public const string PropertyIcePrefix = "ZerocIce_Prefix";
  315. public const string PropertyIceDllExport = "ZerocIce_DllExport";
  316. public const string PropertyVerboseLevel = "ZerocIce_VerboseLevel";
  317. public const string PropertyProjectVersion = "ZerocIce_ProjectVersion";
  318. private static readonly string[] silverlightNames =
  319. {
  320. "Glacier2", "Ice", "IceGrid", "IcePatch2",
  321. "IceStorm"
  322. };
  323. public static string[] getSilverlightNames()
  324. {
  325. return (string[])silverlightNames.Clone();
  326. }
  327. private static readonly string[] cppNames =
  328. {
  329. "Freeze", "Glacier2", "Ice", "IceBox", "IceGrid", "IcePatch2",
  330. "IceSSL", "IceStorm", "IceUtil"
  331. };
  332. public static string[] getCppNames()
  333. {
  334. return (string[])cppNames.Clone();
  335. }
  336. private static readonly string[] dotNetNames =
  337. {
  338. "Glacier2", "Ice", "IceBox", "IceGrid", "IcePatch2",
  339. "IceSSL", "IceStorm"
  340. };
  341. private static readonly string[] dotNetCompactNames =
  342. {
  343. "Glacier2", "Ice", "IceBox", "IceGrid", "IcePatch2",
  344. "IceStorm"
  345. };
  346. public static string[] getDotNetCompactNames()
  347. {
  348. return (string[])dotNetCompactNames.Clone();
  349. }
  350. public static string[] getDotNetNames()
  351. {
  352. return (string[])dotNetNames.Clone();
  353. }
  354. public static string getIceHome()
  355. {
  356. string iceSourceHome = System.Environment.GetEnvironmentVariable("IceSourceHome");
  357. if (iceSourceHome != null && System.IO.Directory.Exists(iceSourceHome) &&
  358. System.IO.File.Exists(Path.Combine(iceSourceHome, Path.Combine("cpp", Path.Combine("bin", slice2cpp)))))
  359. {
  360. return iceSourceHome;
  361. }
  362. else
  363. {
  364. string defaultIceHome = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
  365. if (defaultIceHome.EndsWith("\\vsaddin", StringComparison.CurrentCultureIgnoreCase))
  366. {
  367. defaultIceHome = defaultIceHome.Substring(0, defaultIceHome.Length - "\\vsaddin".Length);
  368. }
  369. else if (defaultIceHome.EndsWith("\\vsaddin\\bin", StringComparison.CurrentCultureIgnoreCase))
  370. {
  371. defaultIceHome = defaultIceHome.Substring(0, defaultIceHome.Length - "\\vsaddin\bin".Length);
  372. }
  373. return defaultIceHome;
  374. }
  375. }
  376. public static string getProjectOutputDirRaw(Project project)
  377. {
  378. return getProjectProperty(project, Util.PropertyIceOutputDir, "", false);
  379. }
  380. public static string getProjectOutputDir(Project project)
  381. {
  382. String path = getProjectOutputDirRaw(project);
  383. if(containsEnvironmentVars(path))
  384. {
  385. path = expandEnvironmentVars(path);
  386. }
  387. return path;
  388. }
  389. public static string getProjectAbsoluteOutputDir(Project project)
  390. {
  391. String path = getProjectOutputDir(project);
  392. if(!Path.IsPathRooted(path))
  393. {
  394. path = Util.absolutePath(project, path);
  395. }
  396. return path;
  397. }
  398. public static VCPropertySheet icePropertySheet(Project project)
  399. {
  400. VCPropertySheet sheet = null;
  401. if(isCppProject(project))
  402. {
  403. VCConfiguration configuration = getActiveVCConfiguration(project);
  404. if(configuration != null)
  405. {
  406. sheet = findPropertySheet(((IVCCollection)configuration.PropertySheets), "ice");
  407. }
  408. }
  409. return sheet;
  410. }
  411. public static VCUserMacro userMacro(Project project, String name)
  412. {
  413. VCPropertySheet sheet = icePropertySheet(project);
  414. VCUserMacro macro = null;
  415. foreach(VCUserMacro m in sheet.UserMacros)
  416. {
  417. if(m.Name.Equals(name))
  418. {
  419. macro = m;
  420. break;
  421. }
  422. }
  423. return macro;
  424. }
  425. public static VCPropertySheet findPropertySheet(IVCCollection propertySheets, string sheetName)
  426. {
  427. VCPropertySheet value = null;
  428. foreach(VCPropertySheet sheet in propertySheets)
  429. {
  430. if(sheet == null || String.IsNullOrEmpty(sheet.Name))
  431. {
  432. continue;
  433. }
  434. if(sheet.Name == sheetName)
  435. {
  436. value = sheet;
  437. break;
  438. }
  439. }
  440. return value;
  441. }
  442. //
  443. // This will add the Ice property sheet to the project.
  444. //
  445. public static void addIcePropertySheet(Project project)
  446. {
  447. VCProject vcProj = (VCProject)project.Object;
  448. string propSheetFileName = "$(ALLUSERSPROFILE)\\ZeroC\\Ice";
  449. #if VS2008
  450. propSheetFileName += ".vsprops";
  451. #endif
  452. #if VS2010 || VS2012
  453. propSheetFileName += ".props";
  454. #endif
  455. //
  456. // All project configurations must include ice.vsprops (vc90) or IceCommon.props (vc100 | vc110)
  457. //
  458. IVCCollection configurations = (IVCCollection)vcProj.Configurations;
  459. string[] cppComponents = Util.getCppNames();
  460. foreach(VCConfiguration vcConfig in configurations)
  461. {
  462. VCPropertySheet newSheet = findPropertySheet(vcConfig.PropertySheets as IVCCollection, "ice");
  463. if(newSheet == null)
  464. {
  465. #if VS2008
  466. string inhertiedPropertySheets = vcConfig.InheritedPropertySheets;
  467. if(String.IsNullOrEmpty(inhertiedPropertySheets) || !inhertiedPropertySheets.Contains(propSheetFileName))
  468. {
  469. if(!String.IsNullOrEmpty(inhertiedPropertySheets) && !inhertiedPropertySheets.EndsWith(";"))
  470. {
  471. inhertiedPropertySheets += " ; ";
  472. }
  473. inhertiedPropertySheets += propSheetFileName;
  474. vcConfig.InheritedPropertySheets = inhertiedPropertySheets;
  475. }
  476. #endif
  477. #if VS2010 || VS2012
  478. newSheet = vcConfig.AddPropertySheet(propSheetFileName);
  479. #endif
  480. }
  481. }
  482. }
  483. public static string getCsBinDir(Project project)
  484. {
  485. string binDir = "";
  486. if(isVBSmartDeviceProject(project) || isCSharpSmartDeviceProject(project))
  487. {
  488. binDir = _csCompactFrameworkBinDirs;
  489. }
  490. else if(isSilverlightProject(project))
  491. {
  492. binDir = _slBinDirs;
  493. }
  494. else
  495. {
  496. binDir = _csBinDirs;
  497. }
  498. return Path.Combine(Util.getIceHome(), binDir);
  499. }
  500. public static string getPathRelativeToProject(ProjectItem item)
  501. {
  502. StringBuilder path = new StringBuilder();
  503. if(item != null)
  504. {
  505. path.Append(Util.getPathRelativeToProject(item, item.ContainingProject.ProjectItems));
  506. }
  507. return path.ToString();
  508. }
  509. public static string getPathRelativeToProject(ProjectItem item, ProjectItems items)
  510. {
  511. StringBuilder path = new StringBuilder();
  512. foreach(ProjectItem i in items)
  513. {
  514. if(i == item)
  515. {
  516. if(path.Length > 0)
  517. {
  518. path.Append("\\");
  519. }
  520. path.Append(i.Name);
  521. break;
  522. }
  523. else if(Util.isProjectItemFilter(i) || Util.isProjectItemFolder(i))
  524. {
  525. string token = Util.getPathRelativeToProject(item, i.ProjectItems);
  526. if(!String.IsNullOrEmpty(token))
  527. {
  528. path.Append(i.Name);
  529. path.Append("\\");
  530. path.Append(token);
  531. break;
  532. }
  533. }
  534. }
  535. return path.ToString();
  536. }
  537. public static bool addCppIncludes(VCCLCompilerTool tool, Project project)
  538. {
  539. if(tool == null || project == null)
  540. {
  541. return false;
  542. }
  543. bool changed = false;
  544. ComponentList includes = new ComponentList(tool.AdditionalIncludeDirectories);
  545. string outputDir = getProjectOutputDirRaw(project);
  546. if(outputDir.Equals(""))
  547. {
  548. outputDir = ".";
  549. }
  550. if(!includes.Contains(outputDir) && !includes.Contains(quote(outputDir)))
  551. {
  552. changed = true;
  553. includes.Add(outputDir);
  554. }
  555. if(changed)
  556. {
  557. tool.AdditionalIncludeDirectories = includes.ToString();
  558. }
  559. return changed;
  560. }
  561. public static void removeCppIncludes(VCCLCompilerTool tool, string iceHome, string generatedDir)
  562. {
  563. if(tool == null || String.IsNullOrEmpty(tool.AdditionalIncludeDirectories))
  564. {
  565. return;
  566. }
  567. bool changed = false;
  568. ComponentList includes = new ComponentList(tool.AdditionalIncludeDirectories);
  569. if(includes.Remove(quote(iceHome + "\\include")) || includes.Remove(iceHome + "\\include"))
  570. {
  571. changed = true;
  572. }
  573. if(!generatedDir.Equals("."))
  574. {
  575. if(includes.Remove(generatedDir))
  576. {
  577. changed = true;
  578. }
  579. }
  580. if(changed)
  581. {
  582. tool.AdditionalIncludeDirectories = includes.ToString();
  583. }
  584. }
  585. public static void removeIcePropertySheet(VCConfiguration configuration)
  586. {
  587. if(configuration == null)
  588. {
  589. return;
  590. }
  591. #if VS2008
  592. ComponentList sheets = new ComponentList(configuration.InheritedPropertySheets);
  593. if(sheets.Remove("$(ALLUSERSPROFILE)\\ZeroC\\ice.vsprops"))
  594. {
  595. configuration.InheritedPropertySheets = sheets.ToString();
  596. }
  597. #endif
  598. #if VS2010 || VS2012
  599. VCPropertySheet sheet = null;
  600. IVCCollection sheets = (IVCCollection)configuration.PropertySheets;
  601. foreach(VCPropertySheet s in sheets)
  602. {
  603. if(!s.PropertySheetFile.Equals(configuration.Evaluate("$(ALLUSERSPROFILE)\\ZeroC\\Ice.props"),
  604. StringComparison.CurrentCultureIgnoreCase))
  605. {
  606. continue;
  607. }
  608. sheet = s;
  609. break;
  610. }
  611. if(sheet != null)
  612. {
  613. configuration.RemovePropertySheet(sheet);
  614. }
  615. #endif
  616. }
  617. private static readonly string _csBinDirs = "\\Assemblies\\";
  618. private static readonly string _csCompactFrameworkBinDirs = "\\Assemblies\\cf\\";
  619. private static readonly string _slBinDirs = "\\Assemblies\\sl\\";
  620. public static bool addDotNetReference(Project project, string component, bool development)
  621. {
  622. if(project == null || String.IsNullOrEmpty(component))
  623. {
  624. return false;
  625. }
  626. VSLangProj.VSProject vsProject = (VSLangProj.VSProject)project.Object;
  627. try
  628. {
  629. Reference r = vsProject.References.Add(component + ".dll");
  630. if (development)
  631. {
  632. r.CopyLocal = false;
  633. }
  634. return true;
  635. }
  636. catch (COMException ex)
  637. {
  638. Console.WriteLine(ex);
  639. }
  640. MessageBox.Show("Could not locate '" + component + ".dll'.",
  641. "Ice Visual Studio Add-in", MessageBoxButtons.OK,
  642. MessageBoxIcon.Error,
  643. MessageBoxDefaultButton.Button1,
  644. (MessageBoxOptions)0);
  645. return false;
  646. }
  647. public static bool removeDotNetReference(Project project, string component)
  648. {
  649. if(project == null || String.IsNullOrEmpty(component))
  650. {
  651. return false;
  652. }
  653. foreach(Reference r in ((VSProject)project.Object).References)
  654. {
  655. if(r.Name.Equals(component, StringComparison.OrdinalIgnoreCase))
  656. {
  657. r.Remove();
  658. return true;
  659. }
  660. }
  661. return false;
  662. }
  663. #if VS2012
  664. public static void addSdkReference(VCProject project, string component)
  665. {
  666. string sdkId = component + ", Version=" + Util.MajorVersion + "." + Util.MinorVersion;
  667. VCReference reference = (VCReference)((VCReferences)project.VCReferences).Item(sdkId);
  668. if(reference != null)
  669. {
  670. reference.Remove();
  671. }
  672. project.AddSdkReference(sdkId);
  673. }
  674. public static bool removeSdkReference(VCProject project, string component)
  675. {
  676. string sdkId = component + ", Version=" + Util.MajorVersion + "." + Util.MinorVersion;
  677. VCReference reference = (VCReference)((VCReferences)project.VCReferences).Item(sdkId);
  678. if (reference != null)
  679. {
  680. reference.Remove();
  681. return true;
  682. }
  683. return false;
  684. }
  685. #endif
  686. public static void addCppLib(LinkerAdapter tool, string component, bool debug)
  687. {
  688. if(tool == null || String.IsNullOrEmpty(component))
  689. {
  690. return;
  691. }
  692. if(Array.BinarySearch(Util.getCppNames(), component, StringComparer.CurrentCultureIgnoreCase) < 0)
  693. {
  694. return;
  695. }
  696. string libName = component;
  697. if(debug)
  698. {
  699. libName += "d";
  700. }
  701. libName += ".lib";
  702. libName = libName.ToLower();
  703. string additionalDependencies = tool.AdditionalDependencies;
  704. if(String.IsNullOrEmpty(additionalDependencies))
  705. {
  706. additionalDependencies = "";
  707. }
  708. ComponentList components = new ComponentList(additionalDependencies.Split(' '));
  709. if(!components.Contains(libName))
  710. {
  711. components.Add(libName);
  712. additionalDependencies = components.ToString(' ');
  713. tool.AdditionalDependencies = additionalDependencies;
  714. }
  715. }
  716. public static bool removeCppLib(LinkerAdapter tool, string component, bool debug)
  717. {
  718. if(tool == null || String.IsNullOrEmpty(tool.AdditionalDependencies))
  719. {
  720. return false;
  721. }
  722. string libName = component;
  723. if(debug)
  724. {
  725. libName += "d";
  726. }
  727. libName += ".lib";
  728. libName = libName.ToLower();
  729. ComponentList components = new ComponentList(tool.AdditionalDependencies.Split(' '));
  730. if(components.Contains(libName))
  731. {
  732. components.Remove(libName);
  733. tool.AdditionalDependencies = components.ToString(' ');
  734. return true;
  735. }
  736. return false;
  737. }
  738. //
  739. // Add the Ice bin path to the debug environment.
  740. //
  741. // Note: Only the last setting in the environment has effect.
  742. //
  743. public static void addIceCppEnvironment(VCDebugSettings debugSettings, Project project)
  744. {
  745. if(debugSettings == null || project == null)
  746. {
  747. return;
  748. }
  749. String value = "PATH=$(IceBin)";
  750. if(String.IsNullOrEmpty(debugSettings.Environment))
  751. {
  752. debugSettings.Environment = value;
  753. return;
  754. }
  755. if(value.Equals(debugSettings.Environment))
  756. {
  757. return;
  758. }
  759. if(String.IsNullOrEmpty(debugSettings.Environment))
  760. {
  761. debugSettings.Environment = value;
  762. return;
  763. }
  764. ComponentList envs = new ComponentList(debugSettings.Environment, '\n');
  765. string path = "";
  766. //
  767. // Find the last in the list that begins: "PATH=" accounting for case and whitespace.
  768. //
  769. int index = -1;
  770. for(int i = 0; i < envs.Count; ++i)
  771. {
  772. string s = envs[i].Trim();
  773. if(s.StartsWith("PATH", StringComparison.CurrentCultureIgnoreCase))
  774. {
  775. if(s.Substring("PATH".Length).Trim().StartsWith("=", StringComparison.CurrentCultureIgnoreCase))
  776. {
  777. path = s;
  778. index = i;
  779. }
  780. }
  781. }
  782. if(index == -1)
  783. {
  784. envs.Add("PATH=$(IceBin)");
  785. }
  786. else
  787. {
  788. string binDir = "$(IceBin)";
  789. ComponentList paths = new ComponentList(assignmentValue(path), ';');
  790. while(paths.Contains(binDir))
  791. {
  792. paths.Remove(binDir);
  793. }
  794. path = "PATH=" + binDir + Path.PathSeparator + paths.ToString(Path.PathSeparator);
  795. path = path.TrimEnd(Path.PathSeparator);
  796. envs[index] = path;
  797. }
  798. value = envs.ToString('\n');
  799. if(!debugSettings.Environment.Equals(value))
  800. {
  801. debugSettings.Environment = value;
  802. }
  803. return;
  804. }
  805. private static string removeFromPath(string path, string dir)
  806. {
  807. ComponentList list = new ComponentList(path.Split(Path.PathSeparator));
  808. while(list.Contains(dir))
  809. {
  810. list.Remove(dir);
  811. }
  812. return list.ToString(Path.PathSeparator);
  813. }
  814. private static string assignmentValue(string expr)
  815. {
  816. int i = expr.IndexOf('=');
  817. if(i < 0)
  818. {
  819. return "";
  820. }
  821. try
  822. {
  823. return expr.Substring(i).Substring(1).Trim();
  824. }
  825. catch(ArgumentOutOfRangeException)
  826. {
  827. return "";
  828. }
  829. }
  830. private static string prependToPath(string path, string dir)
  831. {
  832. path = removeFromPath(path, dir);
  833. return dir + Path.PathSeparator + path;
  834. }
  835. public static string cppBinDir(Project project, CPUType arch)
  836. {
  837. #if VS2010 || VS2012
  838. return isWinRTProject(project) ? "$(IceBin)\\winrt" : "$(IceBin)";
  839. #else
  840. string cppBinDir = Path.Combine("$(IceHome)", "bin");
  841. if(arch == CPUType.x64CPUType)
  842. {
  843. cppBinDir = Path.Combine(cppBinDir, "x64");
  844. }
  845. return cppBinDir;
  846. #endif
  847. }
  848. public static void removeIceCppEnvironment(VCDebugSettings debugSettings, string iceHome)
  849. {
  850. if(debugSettings == null || String.IsNullOrEmpty(debugSettings.Environment))
  851. {
  852. return;
  853. }
  854. string[] _cppBinDirs =
  855. {
  856. "bin",
  857. "bin\\x64",
  858. "bin\\vc100",
  859. "bin\\vc100\\x64",
  860. "cpp\\bin",
  861. };
  862. ComponentList envs = new ComponentList(debugSettings.Environment, '\n');
  863. /* Find the last in the list that begins: "PATH=" accounting for case and whitespace. */
  864. string path = "";
  865. int index = -1;
  866. for(int i = 0; i < envs.Count; ++i)
  867. {
  868. string s = envs[i];
  869. if(s.StartsWith("PATH", StringComparison.CurrentCultureIgnoreCase))
  870. {
  871. if(s.Substring("PATH".Length).Trim().StartsWith("=", StringComparison.CurrentCultureIgnoreCase))
  872. {
  873. path = s;
  874. index = i;
  875. }
  876. }
  877. }
  878. if(index == -1)
  879. {
  880. return;
  881. }
  882. foreach(string dir in _cppBinDirs)
  883. {
  884. path = "PATH=" + removeFromPath(assignmentValue(path).Trim(), Path.Combine(iceHome, dir));
  885. }
  886. #if VS2010 || VS2012
  887. path = "PATH=" + removeFromPath(assignmentValue(path).Trim(), "$(IceBin)\\winrt");
  888. path = "PATH=" + removeFromPath(assignmentValue(path).Trim(), "$(IceBin)");
  889. #endif
  890. if(path.Equals("PATH="))
  891. {
  892. envs.RemoveAt(index);
  893. }
  894. else
  895. {
  896. envs[index] = path;
  897. }
  898. String value = envs.ToString();
  899. if(!debugSettings.Environment.Equals(value))
  900. {
  901. debugSettings.Environment = value;
  902. }
  903. return;
  904. }
  905. public static void removeIceCppLibraryDir(LinkerAdapter tool, string iceHome)
  906. {
  907. if(tool == null || String.IsNullOrEmpty(tool.AdditionalLibraryDirectories))
  908. {
  909. return;
  910. }
  911. bool changed = false;
  912. ComponentList libs = new ComponentList(tool.AdditionalLibraryDirectories);
  913. //
  914. // Old style lib paths. New configurations use $(IceLib) instead.
  915. //
  916. string[] _cppLibDirs =
  917. {
  918. "lib",
  919. "lib\\x64",
  920. "lib\\vc100",
  921. "lib\\vc100\\x64",
  922. };
  923. foreach(string dir in _cppLibDirs)
  924. {
  925. if(libs.Remove(quote(Path.Combine(iceHome, dir))) ||
  926. libs.Remove(Path.Combine(iceHome, dir)))
  927. {
  928. changed = true;
  929. }
  930. }
  931. #if VS2010 || VS2012
  932. if(libs.Remove(quote("$(IceLib)")) ||
  933. libs.Remove("$(IceLib)") ||
  934. libs.Remove(quote("$(IceLib)\\winrt")) ||
  935. libs.Remove("$(IceLib)\\winrt"))
  936. {
  937. changed = true;
  938. }
  939. #endif
  940. if(changed)
  941. {
  942. tool.AdditionalLibraryDirectories = libs.ToString();
  943. }
  944. }
  945. public static bool isSliceFilename(string s)
  946. {
  947. return s != null && s.EndsWith(".ice", StringComparison.CurrentCultureIgnoreCase);
  948. }
  949. public static bool equalPath(string p1, string p2, string basePath)
  950. {
  951. if(p1 == p2)
  952. {
  953. return true;
  954. }
  955. if(String.IsNullOrEmpty(p1) || String.IsNullOrEmpty(p2))
  956. {
  957. return false;
  958. }
  959. //
  960. // Convert both paths to absolute paths if necessary
  961. //
  962. if(!Path.IsPathRooted(p1))
  963. {
  964. p1 = Path.Combine(basePath, p1);
  965. }
  966. if(!Path.IsPathRooted(p2))
  967. {
  968. p2 = Path.Combine(basePath, p2);
  969. }
  970. try
  971. {
  972. //
  973. // Note that in Windows white space at the beginning or end of a file are ignored.
  974. // When comparing the filenames "Foo ", " Foo", and "foo", all refer to the same file.
  975. //
  976. // We also need to trim / (directory separator) from the end in case it's present.
  977. //
  978. return 0 == String.Compare(
  979. Path.GetFullPath(p1).Trim().TrimEnd(Path.DirectorySeparatorChar),
  980. Path.GetFullPath(p2).Trim().TrimEnd(Path.DirectorySeparatorChar),
  981. StringComparison.CurrentCultureIgnoreCase);
  982. }
  983. catch(ArgumentException)
  984. {
  985. }
  986. catch(NotSupportedException)
  987. {
  988. }
  989. catch(System.Security.SecurityException)
  990. {
  991. }
  992. catch(PathTooLongException)
  993. {
  994. }
  995. return false;
  996. }
  997. public static bool isSliceBuilderEnabled(Project project)
  998. {
  999. try
  1000. {
  1001. if(isCppProject(project) ||
  1002. isCSharpProject(project) ||
  1003. isVBProject(project) ||
  1004. isSilverlightProject(project) ||
  1005. isCSharpSmartDeviceProject(project) ||
  1006. isVBSmartDeviceProject(project))
  1007. {
  1008. return Util.getProjectPropertyAsBool(project, Util.PropertyIce);
  1009. }
  1010. }
  1011. catch(System.NotImplementedException)
  1012. {
  1013. }
  1014. return false;
  1015. }
  1016. public static bool isCSharpProject(Project project)
  1017. {
  1018. if(project == null)
  1019. {
  1020. return false;
  1021. }
  1022. if(String.IsNullOrEmpty(project.Kind))
  1023. {
  1024. return false;
  1025. }
  1026. return project.Kind == VSLangProj.PrjKind.prjKindCSharpProject;
  1027. }
  1028. public static bool isCSharpSmartDeviceProject(Project project)
  1029. {
  1030. return hasProjecType(project, vsSmartDeviceCSharp);
  1031. }
  1032. public static bool isVBSmartDeviceProject(Project project)
  1033. {
  1034. return hasProjecType(project, vsSmartDeviceVB);
  1035. }
  1036. public static bool isVBProject(Project project)
  1037. {
  1038. if(project == null)
  1039. {
  1040. return false;
  1041. }
  1042. if(String.IsNullOrEmpty(project.Kind))
  1043. {
  1044. return false;
  1045. }
  1046. return project.Kind == VSLangProj.PrjKind.prjKindVBProject;
  1047. }
  1048. public static bool isSilverlightProject(Project project)
  1049. {
  1050. if(!Util.isCSharpProject(project))
  1051. {
  1052. return false;
  1053. }
  1054. Array extenders = (Array)project.ExtenderNames;
  1055. foreach(string s in extenders)
  1056. {
  1057. if(String.IsNullOrEmpty(s))
  1058. {
  1059. continue;
  1060. }
  1061. if(s.Equals("SilverlightProject"))
  1062. {
  1063. return true;
  1064. }
  1065. }
  1066. return false;
  1067. }
  1068. public static bool isCppProject(Project project)
  1069. {
  1070. if(project == null)
  1071. {
  1072. return false;
  1073. }
  1074. if(String.IsNullOrEmpty(project.Kind))
  1075. {
  1076. return false;
  1077. }
  1078. return project.Kind == vcContextGuids.vcContextGuidVCProject;
  1079. }
  1080. public static bool isWinRTProject(Project project)
  1081. {
  1082. if(isCppProject(project))
  1083. {
  1084. ConfigurationManager configManager = project.ConfigurationManager;
  1085. Configuration activeConfig = (Configuration)configManager.ActiveConfiguration;
  1086. VCProject vcProject = (VCProject)project.Object;
  1087. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  1088. foreach(VCConfiguration conf in configurations)
  1089. {
  1090. if(!activeConfig.PlatformName.Equals(((VCPlatform)conf.Platform).Name))
  1091. {
  1092. continue;
  1093. }
  1094. IVCCollection sheets = (IVCCollection)conf.PropertySheets;
  1095. foreach(VCPropertySheet s in sheets)
  1096. {
  1097. if(s.PropertySheetFile.EndsWith("\\Microsoft.Cpp.AppContainerApplication.props"))
  1098. {
  1099. return true;
  1100. }
  1101. }
  1102. return false;
  1103. }
  1104. }
  1105. return false;
  1106. }
  1107. public static bool isProjectItemFolder(ProjectItem item)
  1108. {
  1109. if(item == null)
  1110. {
  1111. return false;
  1112. }
  1113. if(String.IsNullOrEmpty(item.Kind))
  1114. {
  1115. return false;
  1116. }
  1117. return item.Kind == "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}";
  1118. }
  1119. public static bool isProjectItemFilter(ProjectItem item)
  1120. {
  1121. if(item == null)
  1122. {
  1123. return false;
  1124. }
  1125. if(String.IsNullOrEmpty(item.Kind))
  1126. {
  1127. return false;
  1128. }
  1129. return item.Kind == "{6BB5F8F0-4483-11D3-8BCF-00C04F8EC28C}";
  1130. }
  1131. public static bool isProjectItemFile(ProjectItem item)
  1132. {
  1133. if(item == null)
  1134. {
  1135. return false;
  1136. }
  1137. if(String.IsNullOrEmpty(item.Kind))
  1138. {
  1139. return false;
  1140. }
  1141. return item.Kind == "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}";
  1142. }
  1143. public static bool hasItemNamed(ProjectItems items, string name)
  1144. {
  1145. bool found = false;
  1146. foreach(ProjectItem item in items)
  1147. {
  1148. if(item == null)
  1149. {
  1150. continue;
  1151. }
  1152. if(item.Name == null)
  1153. {
  1154. continue;
  1155. }
  1156. if(item.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
  1157. {
  1158. found = true;
  1159. break;
  1160. }
  1161. }
  1162. return found;
  1163. }
  1164. public static Project findProject(VCProject vcProject)
  1165. {
  1166. if(vcProject == null)
  1167. {
  1168. return null;
  1169. }
  1170. Builder builder = Connect.getBuilder();
  1171. DTE dte = builder.getCurrentDTE();
  1172. if(dte == null)
  1173. {
  1174. return null;
  1175. }
  1176. if(dte.Solution == null)
  1177. {
  1178. return null;
  1179. }
  1180. List<Project> projects = Util.getProjects(dte.Solution);
  1181. Project project = null;
  1182. foreach(Project p in projects)
  1183. {
  1184. if(p.Object != null && p.Object.Equals(vcProject))
  1185. {
  1186. project = p;
  1187. break;
  1188. }
  1189. }
  1190. return project;
  1191. }
  1192. public static ProjectItem findItem(string path)
  1193. {
  1194. Builder builder = Connect.getBuilder();
  1195. DTE dte = builder.getCurrentDTE();
  1196. if(dte == null)
  1197. {
  1198. return null;
  1199. }
  1200. if(dte.Solution == null)
  1201. {
  1202. return null;
  1203. }
  1204. List<Project> projects = Util.getProjects(dte.Solution);
  1205. ProjectItem item = null;
  1206. foreach(Project project in projects)
  1207. {
  1208. item = findItem(path, project.ProjectItems);
  1209. if(item != null)
  1210. {
  1211. break;
  1212. }
  1213. }
  1214. return item;
  1215. }
  1216. public static ProjectItem findItem(string path, ProjectItems items)
  1217. {
  1218. if(String.IsNullOrEmpty(path))
  1219. {
  1220. return null;
  1221. }
  1222. ProjectItem item = null;
  1223. foreach(ProjectItem i in items)
  1224. {
  1225. if(i == null)
  1226. {
  1227. continue;
  1228. }
  1229. else if(Util.isProjectItemFile(i))
  1230. {
  1231. string fullPath = i.Properties.Item("FullPath").Value.ToString();
  1232. Project project = i.ContainingProject;
  1233. if(Util.equalPath(fullPath, path, Path.GetDirectoryName(project.FileName)))
  1234. {
  1235. item = i;
  1236. break;
  1237. }
  1238. }
  1239. else if(Util.isProjectItemFolder(i))
  1240. {
  1241. string p = Path.GetDirectoryName(i.Properties.Item("FullPath").Value.ToString());
  1242. Project project = i.ContainingProject;
  1243. if(Util.equalPath(p, path, Path.GetDirectoryName(project.FileName)))
  1244. {
  1245. item = i;
  1246. break;
  1247. }
  1248. item = findItem(path, i.ProjectItems);
  1249. if(item != null)
  1250. {
  1251. break;
  1252. }
  1253. }
  1254. else if(Util.isProjectItemFilter(i))
  1255. {
  1256. string p = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(i.ContainingProject.FileName),
  1257. Util.getPathRelativeToProject(i)));
  1258. Project project = i.ContainingProject;
  1259. if(Util.equalPath(p, path, Path.GetDirectoryName(project.FileName)))
  1260. {
  1261. item = i;
  1262. break;
  1263. }
  1264. item = findItem(path, i.ProjectItems);
  1265. if(item != null)
  1266. {
  1267. break;
  1268. }
  1269. }
  1270. }
  1271. return item;
  1272. }
  1273. public static VCFile findVCFile(IVCCollection files, string name, string fullPath)
  1274. {
  1275. VCFile vcFile = null;
  1276. foreach(VCFile file in files)
  1277. {
  1278. if(file.ItemName == name)
  1279. {
  1280. Project project = (Project)((VCProject) file.project).Object;
  1281. if(!Util.equalPath(file.FullPath, fullPath, Path.GetDirectoryName(project.FileName)))
  1282. {
  1283. file.Remove();
  1284. break;
  1285. }
  1286. vcFile = file;
  1287. break;
  1288. }
  1289. }
  1290. return vcFile;
  1291. }
  1292. public static string relativePath(Project project, string absoluteFilePath)
  1293. {
  1294. if(absoluteFilePath == null)
  1295. {
  1296. return "";
  1297. }
  1298. if(project == null)
  1299. {
  1300. return absoluteFilePath;
  1301. }
  1302. return relativePath(Path.GetDirectoryName(project.FileName), absoluteFilePath);
  1303. }
  1304. public static string relativePath(string mainDirPath, string absoluteFilePath)
  1305. {
  1306. if(absoluteFilePath == null)
  1307. {
  1308. return "";
  1309. }
  1310. if(mainDirPath == null)
  1311. {
  1312. return absoluteFilePath;
  1313. }
  1314. if(!Path.IsPathRooted(absoluteFilePath))
  1315. {
  1316. return absoluteFilePath;
  1317. }
  1318. mainDirPath = Path.GetFullPath(mainDirPath).Trim(Path.DirectorySeparatorChar);
  1319. absoluteFilePath = Path.GetFullPath(absoluteFilePath).Trim(Path.DirectorySeparatorChar);
  1320. string[] firstPathParts = mainDirPath.Split(Path.DirectorySeparatorChar);
  1321. string[] secondPathParts = absoluteFilePath.Split(Path.DirectorySeparatorChar);
  1322. int sameCounter = 0;
  1323. while(sameCounter < Math.Min(firstPathParts.Length, secondPathParts.Length) &&
  1324. String.Equals(firstPathParts[sameCounter], secondPathParts[sameCounter],
  1325. StringComparison.CurrentCultureIgnoreCase))
  1326. {
  1327. ++sameCounter;
  1328. }
  1329. // Different volumes, relative path not possible.
  1330. if(sameCounter == 0)
  1331. {
  1332. return absoluteFilePath;
  1333. }
  1334. // Pop back up to the common point.
  1335. string newPath = "." + Path.DirectorySeparatorChar;
  1336. for(int i = sameCounter; i < firstPathParts.Length; ++i)
  1337. {
  1338. newPath += ".." + Path.DirectorySeparatorChar;
  1339. }
  1340. // Descend to the target.
  1341. for(int i = sameCounter; i < secondPathParts.Length; ++i)
  1342. {
  1343. newPath += secondPathParts[i] + Path.DirectorySeparatorChar;
  1344. }
  1345. return newPath.TrimEnd(Path.DirectorySeparatorChar);
  1346. }
  1347. // Relative paths are relative to project.
  1348. // Inverse of Util.relativePath().
  1349. public static string absolutePath(Project project, string path)
  1350. {
  1351. if(Path.IsPathRooted(path)) // If path is absolute return that path
  1352. {
  1353. return path;
  1354. }
  1355. return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(project.FileName), path)).TrimEnd(
  1356. Path.DirectorySeparatorChar);
  1357. }
  1358. public static Project getSelectedProject(_DTE dte)
  1359. {
  1360. Microsoft.VisualStudio.Shell.ServiceProvider sp = new Microsoft.VisualStudio.Shell.ServiceProvider(
  1361. getCurrentDTE() as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
  1362. IVsMonitorSelection selectionMonitor = sp.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection;
  1363. //
  1364. // There isn't an open project.
  1365. //
  1366. if(selectionMonitor == null)
  1367. {
  1368. return null;
  1369. }
  1370. Project project = null;
  1371. IntPtr ppHier;
  1372. uint pitemid;
  1373. IVsMultiItemSelect ppMIS;
  1374. IntPtr ppSC;
  1375. if(ErrorHandler.Failed(selectionMonitor.GetCurrentSelection(out ppHier, out pitemid, out ppMIS, out ppSC)))
  1376. {
  1377. return null;
  1378. }
  1379. if(ppHier != IntPtr.Zero)
  1380. {
  1381. IVsHierarchy hier = (IVsHierarchy)Marshal.GetObjectForIUnknown(ppHier);
  1382. Marshal.Release(ppHier);
  1383. object obj;
  1384. hier.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out obj);
  1385. if(obj != null)
  1386. {
  1387. project = obj as EnvDTE.Project;
  1388. }
  1389. }
  1390. if(ppSC != IntPtr.Zero)
  1391. {
  1392. Marshal.Release(ppSC);
  1393. }
  1394. return project;
  1395. }
  1396. public static ProjectItem getSelectedProjectItem(_DTE dte)
  1397. {
  1398. Microsoft.VisualStudio.Shell.ServiceProvider sp = new Microsoft.VisualStudio.Shell.ServiceProvider(
  1399. getCurrentDTE() as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
  1400. IVsMonitorSelection selectionMonitor = sp.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection;
  1401. //
  1402. // There isn't an open project.
  1403. //
  1404. if(selectionMonitor == null)
  1405. {
  1406. return null;
  1407. }
  1408. ProjectItem projectItem = null;
  1409. IntPtr ppHier;
  1410. uint pitemid;
  1411. IVsMultiItemSelect ppMIS;
  1412. IntPtr ppSC;
  1413. if(ErrorHandler.Failed(selectionMonitor.GetCurrentSelection(out ppHier, out pitemid, out ppMIS, out ppSC)))
  1414. {
  1415. return null;
  1416. }
  1417. if(ppHier != IntPtr.Zero)
  1418. {
  1419. IVsHierarchy hier = (IVsHierarchy)Marshal.GetObjectForIUnknown(ppHier);
  1420. Marshal.Release(ppHier);
  1421. object obj;
  1422. hier.GetProperty(pitemid, (int)__VSHPROPID.VSHPROPID_ExtObject, out obj);
  1423. if(obj != null)
  1424. {
  1425. projectItem = obj as EnvDTE.ProjectItem;
  1426. }
  1427. }
  1428. if(ppSC != IntPtr.Zero)
  1429. {
  1430. Marshal.Release(ppSC);
  1431. }
  1432. return projectItem;
  1433. }
  1434. public static bool updateOutputDir(Project project, String outputDir)
  1435. {
  1436. //
  1437. // Note that ouputDir could be empty, which means the project dir will
  1438. // be used as the output directory, and is also the default.
  1439. //
  1440. if(project == null || outputDir == null)
  1441. {
  1442. return false;
  1443. }
  1444. Util.cleanProject(project, true);
  1445. string oldOutputDir = getProjectAbsoluteOutputDir(project);
  1446. string projectDir = Path.GetDirectoryName(project.FileName);
  1447. // Remove old output directory if necessary.
  1448. if(!equalPath(oldOutputDir, projectDir, projectDir) &&
  1449. isEmptyDir(oldOutputDir))
  1450. {
  1451. // In C# projects, diretories are project items, but not in C++ projects.
  1452. if(isCSharpProject(project))
  1453. {
  1454. ProjectItem item = findItem(oldOutputDir, project.ProjectItems);
  1455. if(item != null)
  1456. {
  1457. item.Delete();
  1458. }
  1459. }
  1460. if(Directory.Exists(oldOutputDir))
  1461. {
  1462. Directory.Delete(oldOutputDir, true);
  1463. }
  1464. }
  1465. if(isCppProject(project))
  1466. {
  1467. // We must remove old output directory from C++ project include path.
  1468. removeCppIncludes(project);
  1469. }
  1470. Util.setProjectProperty(project, Util.PropertyIceOutputDir, outputDir);
  1471. if(isCppProject(project))
  1472. {
  1473. // We must add the new output directory to C++ project include path.
  1474. addCppIncludes(project);
  1475. }
  1476. return true;
  1477. }
  1478. public static void removeCppIncludes(Project project)
  1479. {
  1480. if(!isCppProject(project))
  1481. {
  1482. return;
  1483. }
  1484. VCProject vcProject = (VCProject)project.Object;
  1485. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  1486. foreach(VCConfiguration conf in configurations)
  1487. {
  1488. if(conf != null)
  1489. {
  1490. VCCLCompilerTool compilerTool =
  1491. (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
  1492. Util.removeCppIncludes(compilerTool, "$(IceHome)", Util.getProjectOutputDirRaw(project));
  1493. }
  1494. }
  1495. }
  1496. public static void addCppIncludes(Project project)
  1497. {
  1498. if(!isCppProject(project))
  1499. {
  1500. return;
  1501. }
  1502. VCProject vcProject = (VCProject)project.Object;
  1503. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  1504. foreach(VCConfiguration conf in configurations)
  1505. {
  1506. if(conf != null)
  1507. {
  1508. VCCLCompilerTool compilerTool =
  1509. (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
  1510. Util.addCppIncludes(compilerTool, project);
  1511. }
  1512. }
  1513. }
  1514. //
  1515. // Return true if the directory doesn't contain any
  1516. // files. We use this to check if it is safe to delete
  1517. // the output-dir after the user changes the setting.
  1518. //
  1519. public static bool isEmptyDir(String path)
  1520. {
  1521. if(String.IsNullOrEmpty(path))
  1522. {
  1523. return false;
  1524. }
  1525. if(!Directory.Exists(path))
  1526. {
  1527. return false;
  1528. }
  1529. DirectoryInfo dir = new DirectoryInfo(path);
  1530. FileInfo[] files = dir.GetFiles();
  1531. if(files.Length == 0)
  1532. {
  1533. return true;
  1534. }
  1535. bool empty = true;
  1536. foreach(FileInfo f in files)
  1537. {
  1538. if(File.Exists(f.FullName))
  1539. {
  1540. empty = false;
  1541. break;
  1542. }
  1543. else if(Directory.Exists(f.FullName))
  1544. {
  1545. empty = isEmptyDir(f.FullName);
  1546. if(!empty)
  1547. {
  1548. break;
  1549. }
  1550. }
  1551. }
  1552. return empty;
  1553. }
  1554. //
  1555. // The CopyLocal property doesn't work consistently, as sometimes it is set to false
  1556. // when the reference isn't found. This happens when project demos are fisrt
  1557. // opened, as at this point the reference path has not been fixed to use the
  1558. // correct IceHome value. This method returns the private metadata of a
  1559. // Reference from the project file; this value doesn't change as does CopyLocal.
  1560. //
  1561. #if VS2010 || VS2012
  1562. //
  1563. // This method requires .NET 4. Microsoft.Build.BuildEngine is deprecated
  1564. // in .NET 4, so this method uses the new API Microsoft.Build.Evaluation.
  1565. //
  1566. private static bool getCopyLocal(Project project, string name)
  1567. {
  1568. Microsoft.Build.Evaluation.ProjectItem referenceItem = null;
  1569. Microsoft.Build.Evaluation.Project p =
  1570. Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.LoadProject(project.FullName);
  1571. foreach(Microsoft.Build.Evaluation.ProjectItem item in p.Items)
  1572. {
  1573. if(!item.ItemType.Equals("Reference"))
  1574. {
  1575. continue;
  1576. }
  1577. if(!item.HasMetadata("private"))
  1578. {
  1579. continue;
  1580. }
  1581. string[] tokens = item.EvaluatedInclude.Split(',');
  1582. if(tokens.Length <= 0)
  1583. {
  1584. continue;
  1585. }
  1586. if(!tokens[0].Trim().Equals(name, StringComparison.CurrentCultureIgnoreCase))
  1587. {
  1588. continue;
  1589. }
  1590. referenceItem = item;
  1591. if(referenceItem != null)
  1592. {
  1593. break;
  1594. }
  1595. }
  1596. if(referenceItem != null)
  1597. {
  1598. return referenceItem.GetMetadata("Private").EvaluatedValue.Equals(true.ToString(),
  1599. StringComparison.CurrentCultureIgnoreCase);
  1600. }
  1601. return true;
  1602. }
  1603. #elif VS2008
  1604. //
  1605. // This method uses the .NET 3.5 API Microsoft.Build.BuildEngine. This API
  1606. // should not be used with .NET 4 because it has been deprecated.
  1607. //
  1608. private static bool getCopyLocal(Project project, string name)
  1609. {
  1610. Microsoft.Build.BuildEngine.BuildItem referenceItem = null;
  1611. Microsoft.Build.BuildEngine.Project p =
  1612. Microsoft.Build.BuildEngine.Engine.GlobalEngine.GetLoadedProject(project.FileName);
  1613. foreach(Microsoft.Build.BuildEngine.BuildItemGroup itemGroup in p.ItemGroups)
  1614. {
  1615. foreach(Microsoft.Build.BuildEngine.BuildItem item in itemGroup)
  1616. {
  1617. if(!item.Name.Equals("Reference"))
  1618. {
  1619. continue;
  1620. }
  1621. string[] tokens = item.Include.Split(',');
  1622. if(tokens.Length <= 0)
  1623. {
  1624. continue;
  1625. }
  1626. if(!tokens[0].Trim().Equals(name, StringComparison.CurrentCultureIgnoreCase))
  1627. {
  1628. continue;
  1629. }
  1630. referenceItem = item;
  1631. if(referenceItem != null)
  1632. {
  1633. break;
  1634. }
  1635. }
  1636. if(referenceItem != null)
  1637. {
  1638. break;
  1639. }
  1640. }
  1641. if(referenceItem != null)
  1642. {
  1643. return referenceItem.GetMetadata("Private").Equals(true.ToString(),
  1644. StringComparison.CurrentCultureIgnoreCase);
  1645. }
  1646. return true;
  1647. }
  1648. #endif
  1649. private static void setCopyLocal(Project project, string name, bool copyLocal)
  1650. {
  1651. VSLangProj.VSProject vsProject = (VSLangProj.VSProject)project.Object;
  1652. foreach(Reference r in vsProject.References)
  1653. {
  1654. if(r.Name.Equals(name))
  1655. {
  1656. r.CopyLocal = copyLocal;
  1657. break;
  1658. }
  1659. }
  1660. }
  1661. public static int getProjectPropertyAsInt(Project project, string name)
  1662. {
  1663. int value = -1;
  1664. try
  1665. {
  1666. value = Convert.ToInt32(Util.getProjectProperty(project, name), CultureInfo.InvariantCulture);
  1667. }
  1668. catch(FormatException)
  1669. {
  1670. }
  1671. catch(OverflowException)
  1672. {
  1673. }
  1674. return value;
  1675. }
  1676. public static bool getProjectPropertyAsBool(Project project, string name)
  1677. {
  1678. return Util.getProjectProperty(project, name).Equals(
  1679. true.ToString(), StringComparison.CurrentCultureIgnoreCase);
  1680. }
  1681. public static string getProjectProperty(Project project, string name)
  1682. {
  1683. return Util.getProjectProperty(project, name, "", true);
  1684. }
  1685. public static string getProjectProperty(Project project, string name, string defaultValue)
  1686. {
  1687. return Util.getProjectProperty(project, name, defaultValue, true);
  1688. }
  1689. public static string getProjectProperty(Project project, string name, string defaultValue, bool update)
  1690. {
  1691. if(project == null || String.IsNullOrEmpty(name) || project.Globals == null)
  1692. {
  1693. return defaultValue;
  1694. }
  1695. if(project.Globals.get_VariableExists(name))
  1696. {
  1697. return project.Globals[name].ToString();
  1698. }
  1699. if(update)
  1700. {
  1701. if(!String.IsNullOrEmpty(defaultValue))
  1702. {
  1703. project.Globals[name] = defaultValue;
  1704. if(!project.Globals.get_VariablePersists(name))
  1705. {
  1706. project.Globals.set_VariablePersists(name, true);
  1707. }
  1708. }
  1709. }
  1710. return defaultValue;
  1711. }
  1712. public static void setProjectProperty(Project project, string name, string value)
  1713. {
  1714. if(project == null || String.IsNullOrEmpty(name) || project.Globals == null)
  1715. {
  1716. return;
  1717. }
  1718. if(String.IsNullOrEmpty(value))
  1719. {
  1720. if(project.Globals.get_VariableExists(name))
  1721. {
  1722. project.Globals.set_VariablePersists(name, false);
  1723. }
  1724. }
  1725. else if(!project.Globals.get_VariableExists(name) || (string)project.Globals[name] != value)
  1726. {
  1727. project.Globals[name] = value;
  1728. if(!project.Globals.get_VariablePersists(name))
  1729. {
  1730. project.Globals.set_VariablePersists(name, true);
  1731. }
  1732. }
  1733. }
  1734. //
  1735. // As the add-in evolves the code changes, but users still have project files
  1736. // created by previous versions. This method is called when projects are opened
  1737. // to account for old project files and to move them to the current requirements.
  1738. //
  1739. public static void fix(Project p)
  1740. {
  1741. if(p == null || p.Globals == null)
  1742. {
  1743. return;
  1744. }
  1745. //
  1746. // If the project version is the current version we don't need to fix settings.
  1747. //
  1748. if(Util.getProjectProperty(p, PropertyProjectVersion).Equals(ProjectVersion))
  1749. {
  1750. return;
  1751. }
  1752. // This variable was removed for 3.4.1.2.
  1753. if(p.Globals.get_VariableExists("ZerocIce_HomeExpanded"))
  1754. {
  1755. p.Globals.set_VariablePersists("ZerocIce_HomeExpanded", false);
  1756. }
  1757. // This variable was removed for 3.4.2
  1758. if(p.Globals.get_VariableExists("ZerocIce_Home"))
  1759. {
  1760. string iceHome = expandEnvironmentVars(getProjectProperty(p, "ZerocIce_Home"));
  1761. p.Globals.set_VariablePersists("ZerocIce_Home", false);
  1762. if(Util.isCppProject(p))
  1763. {
  1764. //
  1765. // Before 3.4.2 C++ project configurations don't use $(IceHome) macro,
  1766. // we remove these old style settings.
  1767. //
  1768. VCProject vcProject = (VCProject)p.Object;
  1769. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  1770. //
  1771. // Path to property sheet used by VS 2010 projects before 3.4.2,
  1772. // the property sheet is not longer needed and should be removed.
  1773. //
  1774. string sheetFile = Util.absolutePath(p, "ice.props");
  1775. foreach(VCConfiguration conf in configurations)
  1776. {
  1777. if(conf == null)
  1778. {
  1779. continue;
  1780. }
  1781. VCCLCompilerTool compilerTool =
  1782. (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
  1783. bool staticLib = conf.ConfigurationType == Microsoft.VisualStudio.VCProjectEngine.ConfigurationTypes.typeStaticLibrary;
  1784. LinkerAdapter linkerAdapter;
  1785. if(staticLib)
  1786. {
  1787. linkerAdapter = new StaticLinkerAdapter((VCLibrarianTool)(((IVCCollection)conf.Tools).Item("VCLibrarianTool")));
  1788. }
  1789. else
  1790. {
  1791. linkerAdapter = new DynamicLinkerAdapter((VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool")));
  1792. }
  1793. Util.removeIceCppEnvironment((VCDebugSettings)conf.DebugSettings, iceHome);
  1794. Util.removeIceCppLibraryDir(linkerAdapter, iceHome);
  1795. Util.removeIceCppLibraryDir(linkerAdapter, "$(IceHome)");
  1796. Util.removeCppIncludes(compilerTool, iceHome, Util.getProjectOutputDirRaw(p));
  1797. Util.removeCppIncludes(compilerTool, "$(IceHome)", Util.getProjectOutputDirRaw(p));
  1798. //
  1799. // Remove ice.props, old property sheet used by VS 2010
  1800. // from all project configurations.
  1801. //
  1802. #if VS2010 || VS2012
  1803. VCPropertySheet sheet = null;
  1804. IVCCollection sheets = (IVCCollection)conf.PropertySheets;
  1805. foreach(VCPropertySheet s in sheets)
  1806. {
  1807. if(Util.absolutePath(p, s.PropertySheetFile).Equals(sheetFile))
  1808. {
  1809. sheet = s;
  1810. break;
  1811. }
  1812. }
  1813. if(sheet != null)
  1814. {
  1815. conf.RemovePropertySheet(sheet);
  1816. }
  1817. #endif
  1818. }
  1819. //
  1820. // If the old property sheet exists delete it from disk.
  1821. //
  1822. if(File.Exists(sheetFile))
  1823. {
  1824. try
  1825. {
  1826. File.Delete(sheetFile);
  1827. }
  1828. catch(IOException)
  1829. {
  1830. }
  1831. }
  1832. }
  1833. }
  1834. if(Util.isCppProject(p))
  1835. {
  1836. VCProject vcProject = (VCProject)p.Object;
  1837. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  1838. foreach(VCConfiguration conf in configurations)
  1839. {
  1840. if(conf == null)
  1841. {
  1842. continue;
  1843. }
  1844. VCCLCompilerTool compilerTool =
  1845. (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
  1846. bool staticLib = conf.ConfigurationType == Microsoft.VisualStudio.VCProjectEngine.ConfigurationTypes.typeStaticLibrary;
  1847. LinkerAdapter linkerAdapter;
  1848. if(staticLib)
  1849. {
  1850. linkerAdapter = new StaticLinkerAdapter((VCLibrarianTool)(((IVCCollection)conf.Tools).Item("VCLibrarianTool")));
  1851. }
  1852. else
  1853. {
  1854. linkerAdapter = new DynamicLinkerAdapter((VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool")));
  1855. }
  1856. Util.removeIceCppLibraryDir(linkerAdapter, "$(IceHome)");
  1857. Util.removeCppIncludes(compilerTool, "$(IceHome)", Util.getProjectOutputDirRaw(p));
  1858. }
  1859. }
  1860. // This feature was made more general for 3.4.1.2.
  1861. if(p.Globals.get_VariableExists("ZerocIce_ConsoleOutput"))
  1862. {
  1863. if(!p.Globals.get_VariableExists(PropertyVerboseLevel))
  1864. {
  1865. setProjectProperty(p, PropertyVerboseLevel, "0");
  1866. if(getProjectPropertyAsBool(p, "ZerocIce_ConsoleOutput"))
  1867. {
  1868. setProjectProperty(p, PropertyVerboseLevel, "1");
  1869. }
  1870. }
  1871. p.Globals.set_VariablePersists("ZerocIce_ConsoleOutput", false);
  1872. }
  1873. Util.setProjectProperty(p, PropertyProjectVersion, ProjectVersion);
  1874. }
  1875. public static String getPrecompileHeader(Project project, string file)
  1876. {
  1877. String preCompiledHeader = "";
  1878. ProjectItem cppGenerated = Util.findItem(
  1879. Builder.getCppGeneratedFileName(project, file, Util.getSourceExt(project)));
  1880. VCProject cppProject = (VCProject)project.Object;
  1881. VCFile cppFile = null;
  1882. if(cppProject != null && cppGenerated != null)
  1883. {
  1884. IVCCollection files = (IVCCollection)cppProject.Files;
  1885. if(files != null)
  1886. {
  1887. cppFile = (VCFile)files.Item(cppGenerated.Name);
  1888. }
  1889. }
  1890. VCConfiguration configuration = getActiveVCConfiguration(project);
  1891. VCFileConfiguration fileConfiguration = null;
  1892. if(configuration == null)
  1893. {
  1894. return preCompiledHeader;
  1895. }
  1896. if(cppFile != null)
  1897. {
  1898. fileConfiguration = (VCFileConfiguration)((IVCCollection)cppFile.FileConfigurations).Item(configuration.Name);
  1899. }
  1900. VCCLCompilerTool compilerTool = null;
  1901. if(fileConfiguration != null)
  1902. {
  1903. compilerTool = (VCCLCompilerTool)fileConfiguration.Tool;
  1904. }
  1905. else
  1906. {
  1907. compilerTool = (VCCLCompilerTool)(((IVCCollection)configuration.Tools).Item("VCCLCompilerTool"));
  1908. }
  1909. if(compilerTool == null)
  1910. {
  1911. return preCompiledHeader;
  1912. }
  1913. if(compilerTool.UsePrecompiledHeader == pchOption.pchCreateUsingSpecific ||
  1914. compilerTool.UsePrecompiledHeader == pchOption.pchUseUsingSpecific)
  1915. {
  1916. preCompiledHeader = compilerTool.PrecompiledHeaderThrough;
  1917. }
  1918. return preCompiledHeader;
  1919. }
  1920. public static ComponentList getIceCppComponents(Project project)
  1921. {
  1922. ComponentList components = new ComponentList();
  1923. VCProject vcProject = (VCProject)project.Object;
  1924. bool winrt = isWinRTProject(project);
  1925. if(!winrt)
  1926. {
  1927. ConfigurationManager configManager = project.ConfigurationManager;
  1928. Configuration activeConfig = (Configuration)configManager.ActiveConfiguration;
  1929. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  1930. foreach(VCConfiguration conf in configurations)
  1931. {
  1932. if(conf == null)
  1933. {
  1934. continue;
  1935. }
  1936. if(String.IsNullOrEmpty(conf.Name))
  1937. {
  1938. continue;
  1939. }
  1940. if(!conf.Name.Equals(activeConfig.ConfigurationName + "|" + activeConfig.PlatformName))
  1941. {
  1942. continue;
  1943. }
  1944. VCCLCompilerTool compilerTool =
  1945. (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
  1946. VCLinkerTool linkerTool = (VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool"));
  1947. if(linkerTool == null || compilerTool == null)
  1948. {
  1949. break;
  1950. }
  1951. if(String.IsNullOrEmpty(linkerTool.AdditionalDependencies))
  1952. {
  1953. break;
  1954. }
  1955. bool debug = isDebug(compilerTool.RuntimeLibrary);
  1956. List<string> componentNames = new List<string>(linkerTool.AdditionalDependencies.Split(' '));
  1957. foreach(string s in componentNames)
  1958. {
  1959. if(String.IsNullOrEmpty(s))
  1960. {
  1961. continue;
  1962. }
  1963. int index = s.LastIndexOf('.');
  1964. if(index <= 0)
  1965. {
  1966. continue;
  1967. }
  1968. string libName = s.Substring(0, index);
  1969. if(libName.EndsWith("d"))
  1970. {
  1971. libName = libName.Substring(0, libName.Length - 1);
  1972. }
  1973. if(String.IsNullOrEmpty(libName))
  1974. {
  1975. continue;
  1976. }
  1977. if(Array.BinarySearch(Util.getCppNames(), libName, StringComparer.CurrentCultureIgnoreCase) < 0)
  1978. {
  1979. continue;
  1980. }
  1981. components.Add(libName.Trim());
  1982. }
  1983. }
  1984. }
  1985. return components;
  1986. }
  1987. public static ComponentList getIceSilverlightComponents(Project project)
  1988. {
  1989. ComponentList components = new ComponentList();
  1990. if(project == null)
  1991. {
  1992. return components;
  1993. }
  1994. VSLangProj.VSProject vsProject = (VSLangProj.VSProject)project.Object;
  1995. foreach(Reference r in vsProject.References)
  1996. {
  1997. if(Array.BinarySearch(Util.getSilverlightNames(), r.Name, StringComparer.CurrentCultureIgnoreCase) < 0)
  1998. {
  1999. continue;
  2000. }
  2001. components.Add(r.Name);
  2002. }
  2003. return components;
  2004. }
  2005. public static ComponentList getIceDotNetComponents(Project project)
  2006. {
  2007. ComponentList components = new ComponentList();
  2008. if(project == null)
  2009. {
  2010. return components;
  2011. }
  2012. string[] componentNames = null;
  2013. if(Util.isCSharpSmartDeviceProject(project) || Util.isVBSmartDeviceProject(project))
  2014. {
  2015. componentNames = getDotNetCompactNames();
  2016. }
  2017. else if (Util.isSilverlightProject(project))
  2018. {
  2019. componentNames = getSilverlightNames();
  2020. }
  2021. else
  2022. {
  2023. componentNames = getDotNetNames();
  2024. }
  2025. VSLangProj.VSProject vsProject = (VSLangProj.VSProject)project.Object;
  2026. foreach(Reference r in vsProject.References)
  2027. {
  2028. if(Array.BinarySearch(componentNames, r.Name, StringComparer.CurrentCultureIgnoreCase) < 0)
  2029. {
  2030. continue;
  2031. }
  2032. components.Add(r.Name);
  2033. }
  2034. return components;
  2035. }
  2036. public static void addIceCppConfigurations(Project project)
  2037. {
  2038. if(!isCppProject(project))
  2039. {
  2040. return;
  2041. }
  2042. Util.addCppIncludes(project);
  2043. bool winrt = isWinRTProject(project);
  2044. if(!winrt)
  2045. {
  2046. Util.addIcePropertySheet(project);
  2047. }
  2048. #if VS2012
  2049. if(winrt)
  2050. {
  2051. VCProject vcProject = (VCProject)project.Object;
  2052. addSdkReference(vcProject, "Ice");
  2053. }
  2054. #endif
  2055. }
  2056. public static void removeIceCppConfigurations(Project project)
  2057. {
  2058. if(!isCppProject(project))
  2059. {
  2060. return;
  2061. }
  2062. VCProject vcProject = (VCProject)project.Object;
  2063. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  2064. bool winrt = isWinRTProject(project);
  2065. foreach(VCConfiguration conf in configurations)
  2066. {
  2067. if(conf == null)
  2068. {
  2069. continue;
  2070. }
  2071. if(!winrt)
  2072. {
  2073. Util.removeIcePropertySheet(conf);
  2074. }
  2075. }
  2076. Util.removeIceCppLibs(project);
  2077. }
  2078. public static void addIceCppLibs(Project project, ComponentList components)
  2079. {
  2080. if(!isCppProject(project))
  2081. {
  2082. return;
  2083. }
  2084. bool winrt = isWinRTProject(project);
  2085. VCProject vcProject = (VCProject)project.Object;
  2086. if(!winrt)
  2087. {
  2088. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  2089. foreach(VCConfiguration conf in configurations)
  2090. {
  2091. if(conf == null)
  2092. {
  2093. continue;
  2094. }
  2095. VCCLCompilerTool compilerTool =
  2096. (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
  2097. bool staticLib = conf.ConfigurationType == Microsoft.VisualStudio.VCProjectEngine.ConfigurationTypes.typeStaticLibrary;
  2098. LinkerAdapter linkerAdapter;
  2099. if(staticLib)
  2100. {
  2101. linkerAdapter = new StaticLinkerAdapter((VCLibrarianTool)(((IVCCollection)conf.Tools).Item("VCLibrarianTool")));
  2102. }
  2103. else
  2104. {
  2105. linkerAdapter = new DynamicLinkerAdapter((VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool")));
  2106. }
  2107. if(compilerTool == null || linkerAdapter == null)
  2108. {
  2109. continue;
  2110. }
  2111. bool debug = isDebug(compilerTool.RuntimeLibrary);
  2112. foreach(string component in components)
  2113. {
  2114. if(String.IsNullOrEmpty(component))
  2115. {
  2116. continue;
  2117. }
  2118. Util.addCppLib(linkerAdapter, component, debug);
  2119. }
  2120. }
  2121. }
  2122. }
  2123. public static ComponentList removeIceCppLibs(Project project)
  2124. {
  2125. return Util.removeIceCppLibs(project, new ComponentList(Util.getCppNames()));
  2126. }
  2127. public static ComponentList removeIceCppLibs(Project project, ComponentList components)
  2128. {
  2129. ComponentList removed = new ComponentList();
  2130. if(!isCppProject(project))
  2131. {
  2132. return removed;
  2133. }
  2134. bool winrt = isWinRTProject(project);
  2135. VCProject vcProject = (VCProject)project.Object;
  2136. if(!winrt)
  2137. {
  2138. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  2139. foreach(VCConfiguration conf in configurations)
  2140. {
  2141. if(conf == null)
  2142. {
  2143. continue;
  2144. }
  2145. VCCLCompilerTool compilerTool =
  2146. (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
  2147. bool staticLib = conf.ConfigurationType == Microsoft.VisualStudio.VCProjectEngine.ConfigurationTypes.typeStaticLibrary;
  2148. LinkerAdapter linkerAdapter;
  2149. if(staticLib)
  2150. {
  2151. linkerAdapter = new StaticLinkerAdapter((VCLibrarianTool)(((IVCCollection)conf.Tools).Item("VCLibrarianTool")));
  2152. }
  2153. else
  2154. {
  2155. linkerAdapter = new DynamicLinkerAdapter((VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool")));
  2156. }
  2157. if(compilerTool == null || linkerAdapter == null)
  2158. {
  2159. continue;
  2160. }
  2161. bool debug = false;
  2162. if(!String.IsNullOrEmpty(compilerTool.PreprocessorDefinitions))
  2163. {
  2164. debug = (compilerTool.PreprocessorDefinitions.Contains("DEBUG") &&
  2165. !compilerTool.PreprocessorDefinitions.Contains("NDEBUG"));
  2166. }
  2167. if(!debug)
  2168. {
  2169. debug = conf.Name.Contains("Debug");
  2170. }
  2171. foreach(string s in components)
  2172. {
  2173. if(String.IsNullOrEmpty(s))
  2174. {
  2175. continue;
  2176. }
  2177. if(Util.removeCppLib(linkerAdapter, s, debug) && !removed.Contains(s))
  2178. {
  2179. removed.Add(s);
  2180. }
  2181. }
  2182. }
  2183. }
  2184. #if VS2012
  2185. else
  2186. {
  2187. Util.removeSdkReference((VCProject)project.Object, "Ice");
  2188. }
  2189. #endif
  2190. return removed;
  2191. }
  2192. //
  2193. // Return true if the .NET reference that corresponds to the Ice component
  2194. // is present in the given project.
  2195. //
  2196. public static bool hasDotNetReference(Project project, string component)
  2197. {
  2198. bool found = false;
  2199. foreach(Reference r in ((VSProject)project.Object).References)
  2200. {
  2201. if(r.Name.Equals(component, StringComparison.OrdinalIgnoreCase))
  2202. {
  2203. found = true;
  2204. break;
  2205. }
  2206. }
  2207. return found;
  2208. }
  2209. //
  2210. // Return true if at least one of the C++ project configurations contains
  2211. // the library corresponding to the given component.
  2212. //
  2213. public static bool hasIceCppLib(Project project, string component)
  2214. {
  2215. if(!isCppProject(project))
  2216. {
  2217. return false;
  2218. }
  2219. if(Array.BinarySearch(Util.getCppNames(), component, StringComparer.CurrentCultureIgnoreCase) < 0)
  2220. {
  2221. return false;
  2222. }
  2223. bool winrt = isWinRTProject(project);
  2224. VCProject vcProject = (VCProject)project.Object;
  2225. bool found = false;
  2226. if(!winrt)
  2227. {
  2228. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  2229. foreach(VCConfiguration conf in configurations)
  2230. {
  2231. if(conf == null)
  2232. {
  2233. continue;
  2234. }
  2235. VCCLCompilerTool compilerTool =
  2236. (VCCLCompilerTool)(((IVCCollection)conf.Tools).Item("VCCLCompilerTool"));
  2237. bool staticLib = conf.ConfigurationType == Microsoft.VisualStudio.VCProjectEngine.ConfigurationTypes.typeStaticLibrary;
  2238. LinkerAdapter linkerAdapter;
  2239. if(staticLib)
  2240. {
  2241. linkerAdapter = new StaticLinkerAdapter((VCLibrarianTool)(((IVCCollection)conf.Tools).Item("VCLibrarianTool")));
  2242. }
  2243. else
  2244. {
  2245. linkerAdapter = new DynamicLinkerAdapter((VCLinkerTool)(((IVCCollection)conf.Tools).Item("VCLinkerTool")));
  2246. }
  2247. if(compilerTool == null || linkerAdapter == null)
  2248. {
  2249. continue;
  2250. }
  2251. bool debug = false;
  2252. if(!String.IsNullOrEmpty(compilerTool.PreprocessorDefinitions))
  2253. {
  2254. debug = (compilerTool.PreprocessorDefinitions.Contains("DEBUG") &&
  2255. !compilerTool.PreprocessorDefinitions.Contains("NDEBUG"));
  2256. }
  2257. if(!debug)
  2258. {
  2259. debug = conf.Name.Contains("Debug");
  2260. }
  2261. string libName = component;
  2262. if(debug)
  2263. {
  2264. libName += "d";
  2265. }
  2266. libName += ".lib";
  2267. string additionalDependencies = linkerAdapter.AdditionalDependencies;
  2268. if(String.IsNullOrEmpty(additionalDependencies))
  2269. {
  2270. continue;
  2271. }
  2272. ComponentList components = new ComponentList(additionalDependencies.Split(' '));
  2273. if(components.Contains(libName))
  2274. {
  2275. found = true;
  2276. break;
  2277. }
  2278. }
  2279. }
  2280. return found;
  2281. }
  2282. public static DTE getCurrentDTE()
  2283. {
  2284. return Connect.getCurrentDTE();
  2285. }
  2286. public static string expandEnvironmentVars(string s)
  2287. {
  2288. if(String.IsNullOrEmpty(s))
  2289. {
  2290. return s;
  2291. }
  2292. string result = s;
  2293. int beg = 0;
  2294. int end = 0;
  2295. while(beg < result.Length &&
  2296. (beg = result.IndexOf("$(", beg, StringComparison.Ordinal)) != -1 &&
  2297. (end = result.IndexOf(")", beg, StringComparison.Ordinal)) != -1)
  2298. {
  2299. string variable = result.Substring(beg + "$(".Length, end - (beg + "$(".Length));
  2300. string value = System.Environment.GetEnvironmentVariable(variable);
  2301. if(value == null)
  2302. {
  2303. // Skip undefined vars.
  2304. beg += "$(".Length + variable.Length + ")".Length;
  2305. continue;
  2306. }
  2307. result = result.Replace("$(" + variable + ")", value);
  2308. beg += value.Length;
  2309. }
  2310. return result;
  2311. }
  2312. public static bool containsEnvironmentVars(string s)
  2313. {
  2314. if(String.IsNullOrEmpty(s))
  2315. {
  2316. return false;
  2317. }
  2318. return s.Contains("$(");
  2319. }
  2320. public static string quote(string arg)
  2321. {
  2322. if(String.IsNullOrEmpty(arg))
  2323. {
  2324. return "\"\"";
  2325. }
  2326. return "\"" + arg + "\"";
  2327. }
  2328. public static void verifyProjectSettings(Project project)
  2329. {
  2330. if(isCppProject(project))
  2331. {
  2332. addIceCppConfigurations(project);
  2333. }
  2334. }
  2335. public static bool addBuilderToProject(Project project, ComponentList components)
  2336. {
  2337. Builder builder = Connect.getBuilder();
  2338. if(builder == null || project == null)
  2339. {
  2340. return false;
  2341. }
  2342. if(Util.isSliceBuilderEnabled(project))
  2343. {
  2344. return false; // Already enabled.
  2345. }
  2346. builder.addBuilderToProject(project, components);
  2347. return true;
  2348. }
  2349. public static bool removeBuilderFromProject(Project project, ComponentList components)
  2350. {
  2351. Builder builder = Connect.getBuilder();
  2352. if(builder == null || project == null)
  2353. {
  2354. return false;
  2355. }
  2356. if(!Util.isSliceBuilderEnabled(project))
  2357. {
  2358. return false; // Already disabled.
  2359. }
  2360. builder.removeBuilderFromProject(project, components);
  2361. return true;
  2362. }
  2363. public static void cleanProject(Project project, bool remove)
  2364. {
  2365. Builder builder = Connect.getBuilder();
  2366. builder.cleanProject(project, remove);
  2367. }
  2368. public static void rebuildProject(Project project)
  2369. {
  2370. Builder builder = Connect.getBuilder();
  2371. builder.cleanProject(project, false);
  2372. builder.buildProject(project, true, vsBuildScope.vsBuildScopeProject, true);
  2373. }
  2374. public static int getVerboseLevel(Project p)
  2375. {
  2376. int verboseLevel = (int)Util.msgLevel.msgInfo;
  2377. if(p != null)
  2378. {
  2379. try
  2380. {
  2381. verboseLevel = Int32.Parse(Util.getProjectProperty(p, Util.PropertyVerboseLevel),
  2382. CultureInfo.InvariantCulture);
  2383. }
  2384. catch(ArgumentNullException)
  2385. {
  2386. }
  2387. catch(FormatException)
  2388. {
  2389. }
  2390. catch(OverflowException)
  2391. {
  2392. }
  2393. }
  2394. return verboseLevel;
  2395. }
  2396. public static void write(Project p, Util.msgLevel msgLevel, string message)
  2397. {
  2398. Builder builder = Connect.getBuilder();
  2399. if(builder == null)
  2400. {
  2401. return;
  2402. }
  2403. int verboseLevel = getVerboseLevel(p);
  2404. if((int)msgLevel <= verboseLevel)
  2405. {
  2406. if(!builder.commandLine)
  2407. {
  2408. OutputWindowPane pane = builder.buildOutput();
  2409. if(pane == null)
  2410. {
  2411. return;
  2412. }
  2413. pane.Activate();
  2414. pane.OutputString(message);
  2415. }
  2416. else
  2417. {
  2418. System.Console.Write(message);
  2419. }
  2420. }
  2421. }
  2422. //
  2423. // Get the assembly name of a .NET project
  2424. //
  2425. public static string assemblyName(Project project)
  2426. {
  2427. if(project == null)
  2428. {
  2429. return "";
  2430. }
  2431. if(!isCSharpProject(project) && !isVBProject(project))
  2432. {
  2433. return "";
  2434. }
  2435. Property assemblyName = project.Properties.Item("AssemblyName");
  2436. if(assemblyName.Value == null)
  2437. {
  2438. return "";
  2439. }
  2440. return assemblyName.Value.ToString();
  2441. }
  2442. //
  2443. // Check if the Visual Studio hosting process is enabled in any of
  2444. // the project configurations.
  2445. //
  2446. public static bool useVSHostingProcess(Project p)
  2447. {
  2448. bool enabled = false;
  2449. foreach(Configuration config in p.ConfigurationManager)
  2450. {
  2451. if(config.Properties == null)
  2452. {
  2453. continue;
  2454. }
  2455. Property property = config.Properties.Item("UseVSHostingProcess");
  2456. if(property.Value.ToString().Equals(true.ToString(), StringComparison.CurrentCultureIgnoreCase))
  2457. {
  2458. enabled = true;
  2459. break;
  2460. }
  2461. }
  2462. return enabled;
  2463. }
  2464. //
  2465. // Enable/Disable the Visual Studio hosting process. We use this
  2466. // to force Visual Studio to restart the hosting process, which is
  2467. // necessary for the process to run with updated environment variables.
  2468. //
  2469. public static void setVsHostingProcess(Project p, bool value)
  2470. {
  2471. foreach(Configuration config in p.ConfigurationManager)
  2472. {
  2473. if(config == null)
  2474. {
  2475. continue;
  2476. }
  2477. if(config.Properties == null)
  2478. {
  2479. continue;
  2480. }
  2481. Property property = config.Properties.Item("UseVSHostingProcess");
  2482. if(property == null)
  2483. {
  2484. continue;
  2485. }
  2486. if(property.Value != null)
  2487. {
  2488. if(property.Value.ToString().Equals(value.ToString(), StringComparison.CurrentCultureIgnoreCase))
  2489. {
  2490. continue;
  2491. }
  2492. }
  2493. property.Value = value;
  2494. }
  2495. }
  2496. //
  2497. // Check if the .NET development mode is enabled in the application config that resides in
  2498. // the file <applicationName>.exe.config.
  2499. //
  2500. public static bool developmentMode(Project project)
  2501. {
  2502. string configPath =
  2503. Path.Combine(Path.GetDirectoryName(project.FileName), assemblyName(project) + ".exe.config");
  2504. if(!File.Exists(configPath))
  2505. {
  2506. return false;
  2507. }
  2508. System.Xml.XmlDocument dom = new System.Xml.XmlDocument();
  2509. try
  2510. {
  2511. dom.Load(configPath);
  2512. System.Xml.XmlNodeList nodes = dom.SelectNodes("/configuration/runtime/developmentMode");
  2513. if(nodes.Count <= 0)
  2514. {
  2515. return false;
  2516. }
  2517. System.Xml.XmlNode node = nodes[0];
  2518. System.Xml.XmlAttribute attribute = node.Attributes["developerInstallation"];
  2519. if(attribute == null)
  2520. {
  2521. return false;
  2522. }
  2523. if(String.IsNullOrEmpty(attribute.Value))
  2524. {
  2525. return false;
  2526. }
  2527. return attribute.Value.Equals("true", StringComparison.CurrentCultureIgnoreCase);
  2528. }
  2529. catch(System.Xml.XmlException)
  2530. {
  2531. return false; // There was an error parsing the XML
  2532. }
  2533. }
  2534. public static bool parseSlice2csOptions(string args, bool showWarning, ref Options opts)
  2535. {
  2536. try
  2537. {
  2538. opts = null;
  2539. if(String.IsNullOrEmpty(args))
  2540. {
  2541. return true; //No options to parse
  2542. }
  2543. opts = new Options();
  2544. opts.addOpt("h", "help");
  2545. opts.addOpt("v", "version");
  2546. opts.addOpt("D", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
  2547. opts.addOpt("U", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
  2548. opts.addOpt("I", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
  2549. opts.addOpt("E");
  2550. opts.addOpt("", "output-dir", Options.ArgType.NeedArg);
  2551. opts.addOpt("", "tie");
  2552. opts.addOpt("", "impl");
  2553. opts.addOpt("", "impl-tie");
  2554. opts.addOpt("", "depend");
  2555. opts.addOpt("d", "debug");
  2556. opts.addOpt("", "ice");
  2557. opts.addOpt("", "underscore");
  2558. opts.addOpt("", "checksum");
  2559. opts.addOpt("", "stream");
  2560. opts.parse(Options.split(args));
  2561. checkInvalidOptions(opts);
  2562. return true;
  2563. }
  2564. catch(BadOptionException ex)
  2565. {
  2566. if(showWarning)
  2567. {
  2568. showExtraOptionsWarning(ex);
  2569. }
  2570. return false;
  2571. }
  2572. }
  2573. public static bool parseSlice2cppOptions(string args, bool showWarning, ref Options opts,
  2574. ref string headerExt, ref string sourceExt)
  2575. {
  2576. try
  2577. {
  2578. opts = null;
  2579. headerExt = "";
  2580. sourceExt = "";
  2581. if(String.IsNullOrEmpty(args))
  2582. {
  2583. return true; //No options to parse
  2584. }
  2585. opts = new Options();
  2586. opts.addOpt("h", "help");
  2587. opts.addOpt("v", "version");
  2588. opts.addOpt("", "header-ext", Options.ArgType.NeedArg, "h");
  2589. opts.addOpt("", "source-ext", Options.ArgType.NeedArg, "cpp");
  2590. opts.addOpt("", "add-header", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
  2591. opts.addOpt("D", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
  2592. opts.addOpt("U", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
  2593. opts.addOpt("I", "", Options.ArgType.NeedArg, "", Options.RepeatType.Repeat);
  2594. opts.addOpt("E");
  2595. opts.addOpt("", "include-dir", Options.ArgType.NeedArg);
  2596. opts.addOpt("", "output-dir", Options.ArgType.NeedArg);
  2597. opts.addOpt("", "dll-export", Options.ArgType.NeedArg);
  2598. opts.addOpt("", "impl");
  2599. opts.addOpt("", "depend");
  2600. opts.addOpt("d", "debug");
  2601. opts.addOpt("", "ice");
  2602. opts.addOpt("", "underscore");
  2603. opts.addOpt("", "checksum");
  2604. opts.addOpt("", "stream");
  2605. opts.parse(Options.split(args));
  2606. checkInvalidOptions(opts);
  2607. string hExt = opts.optArg("header-ext");
  2608. string cppExt = opts.optArg("source-ext");
  2609. if(Util.containsEnvironmentVars(hExt) ||
  2610. Util.containsEnvironmentVars(cppExt))
  2611. {
  2612. throw new BadOptionException(
  2613. "You cannot use environment variables in `--header-ext' or `--source-ext' options.");
  2614. }
  2615. headerExt = hExt;
  2616. sourceExt = cppExt;
  2617. if(opts.isSet("dll-export"))
  2618. {
  2619. throw new BadOptionException(
  2620. "Use the `DLL Export Symbol' text box below to set the --dll-export option\n" +
  2621. "instead of the `Extra Compiler Options' text box.");
  2622. }
  2623. return true;
  2624. }
  2625. catch(BadOptionException ex)
  2626. {
  2627. if(showWarning)
  2628. {
  2629. showExtraOptionsWarning(ex);
  2630. }
  2631. return false;
  2632. }
  2633. }
  2634. //
  2635. // Check for common options that must not appear in Extra Options textbox.
  2636. //
  2637. private static void checkInvalidOptions(Options opts)
  2638. {
  2639. if(opts.isSet("output-dir"))
  2640. {
  2641. throw new BadOptionException(
  2642. "Use the `Output Dir' text box above to set `--output-dir' option\n" +
  2643. "instead of the `Extra Compiler Options' text box.");
  2644. }
  2645. if(opts.isSet("depend"))
  2646. {
  2647. throw new BadOptionException("Don't use `--depend' option in `Extra Options' text box.");
  2648. }
  2649. if(opts.isSet("help"))
  2650. {
  2651. throw new BadOptionException("Don't use `--help' or `-h' option in `Extra Options' text box.");
  2652. }
  2653. if(opts.isSet("version"))
  2654. {
  2655. throw new BadOptionException("Don't use `--version' or `-v' option in `Extra Options' text box.");
  2656. }
  2657. }
  2658. private static void showRunTimeLibraryWarning(Project p)
  2659. {
  2660. string err = "Run Time library not supported with Ice, Ice requires /MD or /MDd Run Time Library.";
  2661. MessageBox.Show(err, "Ice Visual Studio Add-in", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1,
  2662. (MessageBoxOptions)0);
  2663. Util.write(p, msgLevel.msgError, err);
  2664. }
  2665. private static void showExtraOptionsWarning(BadOptionException ex)
  2666. {
  2667. MessageBox.Show("Extra Options field contains some errors:\n" +
  2668. ex.reason,
  2669. "Ice Visual Studio Add-in", MessageBoxButtons.OK,
  2670. MessageBoxIcon.Error,
  2671. MessageBoxDefaultButton.Button1,
  2672. (MessageBoxOptions)0);
  2673. }
  2674. public static void unexpectedExceptionWarning(Exception ex)
  2675. {
  2676. string message = "";
  2677. if (ex is InitializationException)
  2678. {
  2679. message = ex.Message;
  2680. }
  2681. else
  2682. {
  2683. message = ex.ToString();
  2684. }
  2685. try
  2686. {
  2687. Builder builder = Connect.getBuilder();
  2688. if(!builder.commandLine)
  2689. {
  2690. MessageBox.Show("The Ice Visual Studio Add-in has raised an unexpected exception:\n" +
  2691. message,
  2692. "Ice Visual Studio Add-in", MessageBoxButtons.OK,
  2693. MessageBoxIcon.Error,
  2694. MessageBoxDefaultButton.Button1,
  2695. (MessageBoxOptions)0);
  2696. }
  2697. }
  2698. catch(Exception)
  2699. {
  2700. }
  2701. try
  2702. {
  2703. Util.write(null, Util.msgLevel.msgError, message + "\n");
  2704. }
  2705. catch(Exception)
  2706. {
  2707. }
  2708. }
  2709. public static string getHeaderExt(Project p)
  2710. {
  2711. String extension = getProjectProperty(p, Util.PropertyIceHeaderExt);
  2712. if(String.IsNullOrEmpty(extension))
  2713. {
  2714. extension = "h";
  2715. }
  2716. return extension;
  2717. }
  2718. public static string getSourceExt(Project p)
  2719. {
  2720. String extension = getProjectProperty(p, Util.PropertyIceSourceExt);
  2721. if(String.IsNullOrEmpty(extension))
  2722. {
  2723. extension = "cpp";
  2724. }
  2725. return extension;
  2726. }
  2727. //
  2728. // Warn the user about unsaved changes. Returns true if the user
  2729. // wants to discard changes, otherwise returns false.
  2730. //
  2731. public static bool warnUnsavedChanges(IWin32Window owner)
  2732. {
  2733. if(MessageBox.Show(owner, "Are you sure you want to discard all changes?",
  2734. "Ice Visual Studio Add-in", MessageBoxButtons.YesNo,
  2735. MessageBoxIcon.Question, MessageBoxDefaultButton.Button1,
  2736. (MessageBoxOptions)0) == DialogResult.Yes)
  2737. {
  2738. return true;
  2739. }
  2740. return false;
  2741. }
  2742. public static List<ProjectItem> clone(ProjectItems items)
  2743. {
  2744. List<ProjectItem> list = new List<ProjectItem>();
  2745. foreach(ProjectItem i in items)
  2746. {
  2747. list.Add(i);
  2748. }
  2749. return list;
  2750. }
  2751. public static String getCommandLineArgument(String arg)
  2752. {
  2753. String value = "";
  2754. DTE2 applicationObject = Connect.getApplicationObject();
  2755. if(!String.IsNullOrEmpty(applicationObject.CommandLineArguments))
  2756. {
  2757. if(applicationObject.CommandLineArguments.IndexOf(arg) != -1)
  2758. {
  2759. String[] args = applicationObject.CommandLineArguments.Split(' ');
  2760. for(int i = 0; i < args.Length; ++i)
  2761. {
  2762. //
  2763. // We found the argument name next item
  2764. // is the argument value.
  2765. //
  2766. if(args[i].Equals(arg))
  2767. {
  2768. if(i < args.Length - 1)
  2769. {
  2770. value = args[i + 1];
  2771. }
  2772. break;
  2773. }
  2774. }
  2775. }
  2776. }
  2777. return value;
  2778. }
  2779. public static Project getProjectByNameOrFile(Solution solution, string name)
  2780. {
  2781. Project project = null;
  2782. List<Project> projects = getProjects(solution);
  2783. foreach(Project p in projects)
  2784. {
  2785. if(p.UniqueName.Equals(name) ||
  2786. p.Name.Equals(name) ||
  2787. Path.GetFullPath(Path.Combine(Path.GetDirectoryName(solution.FullName), name)).Equals(
  2788. Path.GetFullPath(p.FullName)))
  2789. {
  2790. project = p;
  2791. break;
  2792. }
  2793. }
  2794. return project;
  2795. }
  2796. public static List<Project> getProjects(Solution solution)
  2797. {
  2798. List<Project> projects = new List<Project>();
  2799. foreach(Project p in solution.Projects)
  2800. {
  2801. if(String.IsNullOrEmpty(p.Kind) || p.Kind.Equals(unloadedProjectGUID))
  2802. {
  2803. continue;
  2804. }
  2805. if(projects.Contains(p))
  2806. {
  2807. continue;
  2808. }
  2809. getProjects(solution, p, ref projects);
  2810. }
  2811. return projects;
  2812. }
  2813. public static void getProjects(Solution solution, Project project, ref List<Project> projects)
  2814. {
  2815. if(String.IsNullOrEmpty(project.Kind) || project.Kind.Equals(unloadedProjectGUID))
  2816. {
  2817. return;
  2818. }
  2819. if(project.Kind == EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder)
  2820. {
  2821. foreach(ProjectItem item in project.ProjectItems)
  2822. {
  2823. Project p = item.Object as Project;
  2824. if(p == null)
  2825. {
  2826. continue;
  2827. }
  2828. getProjects(solution, p, ref projects);
  2829. }
  2830. return;
  2831. }
  2832. if(!Util.isSliceBuilderEnabled(project))
  2833. {
  2834. // If builder isn't enabled we don't care about the project.
  2835. return;
  2836. }
  2837. if(!projects.Contains(project))
  2838. {
  2839. projects.Add(project);
  2840. }
  2841. }
  2842. //
  2843. // Rerturn a list of projects with match the build order
  2844. // of the solution and have Slice builder enabled.
  2845. //
  2846. public static List<Project> buildOrder(Solution solution)
  2847. {
  2848. List<Project> projects = new List<Project>();
  2849. foreach(Project p in solution.Projects)
  2850. {
  2851. if(String.IsNullOrEmpty(p.Kind) || p.Kind.Equals(unloadedProjectGUID))
  2852. {
  2853. continue;
  2854. }
  2855. if(projects.Contains(p))
  2856. {
  2857. continue;
  2858. }
  2859. buildOrder(solution, p, ref projects);
  2860. }
  2861. return projects;
  2862. }
  2863. //
  2864. // This method helps to build the list of projects with the
  2865. // right build order.
  2866. //
  2867. public static void buildOrder(Solution solution, Project project, ref List<Project> projects)
  2868. {
  2869. if(String.IsNullOrEmpty(project.Kind) || project.Kind.Equals(unloadedProjectGUID))
  2870. {
  2871. return;
  2872. }
  2873. if(project.Kind == EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder)
  2874. {
  2875. foreach(ProjectItem item in project.ProjectItems)
  2876. {
  2877. Project p = item.Object as Project;
  2878. if(p == null)
  2879. {
  2880. continue;
  2881. }
  2882. buildOrder(solution, p, ref projects);
  2883. }
  2884. return;
  2885. }
  2886. if(!Util.isSliceBuilderEnabled(project))
  2887. {
  2888. // If builder isn't enabled we don't care about the project.
  2889. return;
  2890. }
  2891. if(projects.Contains(project))
  2892. {
  2893. return;
  2894. }
  2895. BuildDependencies dependencies = solution.SolutionBuild.BuildDependencies;
  2896. for(int i = 0; i < dependencies.Count; ++i)
  2897. {
  2898. BuildDependency dp = dependencies.Item(i + 1);
  2899. if(dp.Project.Equals(project))
  2900. {
  2901. System.Array requiredProjects = dp.RequiredProjects as System.Array;
  2902. if(requiredProjects == null)
  2903. {
  2904. continue;
  2905. }
  2906. foreach(Project p in requiredProjects)
  2907. {
  2908. Util.buildOrder(solution, p, ref projects);
  2909. }
  2910. }
  2911. }
  2912. if(!projects.Contains(project))
  2913. {
  2914. projects.Add(project);
  2915. }
  2916. }
  2917. public static List<Project> solutionFolderProjects(Project project)
  2918. {
  2919. List<Project> projects = new List<Project>();
  2920. if(!project.Kind.Equals(EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder))
  2921. {
  2922. return projects;
  2923. }
  2924. solutionFolderProjects(project, ref projects);
  2925. return projects;
  2926. }
  2927. public static void solutionFolderProjects(Project project, ref List<Project> projects)
  2928. {
  2929. if(project.Kind.Equals(EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder))
  2930. {
  2931. foreach(ProjectItem item in project.ProjectItems)
  2932. {
  2933. Project p = item.Object as Project;
  2934. if(p == null)
  2935. {
  2936. continue;
  2937. }
  2938. solutionFolderProjects(p, ref projects);
  2939. }
  2940. }
  2941. if(!Util.isSliceBuilderEnabled(project))
  2942. {
  2943. // If builder isn't enabled we don't care about the project.
  2944. return;
  2945. }
  2946. else if(!projects.Contains(project))
  2947. {
  2948. projects.Add(project);
  2949. }
  2950. }
  2951. //
  2952. // This methods refresh the solution explorer if the command
  2953. // is available.
  2954. //
  2955. public static void solutionExplorerRefresh()
  2956. {
  2957. if(_refreshCommand != null && _refreshCommand.IsAvailable)
  2958. {
  2959. DTE dte = getCurrentDTE();
  2960. object objIn = null;
  2961. object objOut = null;
  2962. dte.Commands.Raise(refreshCommandGUID, refreshCommandID, ref objIn, ref objOut);
  2963. }
  2964. }
  2965. public static void setRefreshCommand(Command command)
  2966. {
  2967. _refreshCommand = command;
  2968. }
  2969. static public bool hasProjecType(Project project, string type)
  2970. {
  2971. ComponentList types = new ComponentList(getProjectTypeGuids(project), ';');
  2972. return types.Contains(type);
  2973. }
  2974. static public string getProjectTypeGuids(Project proj)
  2975. {
  2976. string guids = "";
  2977. Microsoft.VisualStudio.Shell.Interop.IVsHierarchy hierarchy = null;
  2978. Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject aggregatableProject = null;
  2979. IVsSolution solution = getIVsSolution();
  2980. int result = solution.GetProjectOfUniqueName(proj.UniqueName, out hierarchy);
  2981. if(result == 0)
  2982. {
  2983. try
  2984. {
  2985. aggregatableProject = (Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject)hierarchy;
  2986. result = aggregatableProject.GetAggregateProjectTypeGuids(out guids);
  2987. }
  2988. catch(InvalidCastException)
  2989. {
  2990. }
  2991. }
  2992. return guids;
  2993. }
  2994. static private IVsSolution getIVsSolution()
  2995. {
  2996. Guid serviceGuid = typeof(SVsSolution).GUID;
  2997. Guid interfaceGuid = typeof(IVsSolution).GUID;
  2998. IntPtr ppObject;
  2999. Microsoft.VisualStudio.OLE.Interop.IServiceProvider serviceProvider =
  3000. (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)getCurrentDTE();
  3001. if(ErrorHandler.Failed(serviceProvider.QueryService(ref serviceGuid, ref interfaceGuid, out ppObject)))
  3002. {
  3003. return null;
  3004. }
  3005. IVsSolution service = null;
  3006. if(!ppObject.Equals(IntPtr.Zero))
  3007. {
  3008. service = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(ppObject) as IVsSolution;
  3009. System.Runtime.InteropServices.Marshal.Release(ppObject);
  3010. }
  3011. return service;
  3012. }
  3013. //
  3014. // Check if we are using a debug run-time library.
  3015. //
  3016. static public bool isDebug(runtimeLibraryOption rt)
  3017. {
  3018. return rt == runtimeLibraryOption.rtMultiThreadedDebug || rt == runtimeLibraryOption.rtMultiThreadedDebugDLL;
  3019. }
  3020. //
  3021. // Check if the run time library is supported with Ice projects
  3022. //
  3023. static public bool checkCppRunTimeLibrary(Project p, runtimeLibraryOption rt)
  3024. {
  3025. return rt == runtimeLibraryOption.rtMultiThreadedDebugDLL || rt == runtimeLibraryOption.rtMultiThreadedDLL;
  3026. }
  3027. static public bool checkCppRunTimeLibrary(Builder builder, Project project, VCCLCompilerTool compilerTool,
  3028. LinkerAdapter linkerTool)
  3029. {
  3030. //
  3031. // Check the project run time library for the active configuration.
  3032. //
  3033. if(!Util.checkCppRunTimeLibrary(project, compilerTool.RuntimeLibrary))
  3034. {
  3035. builder.addError(project, "", TaskErrorCategory.Error, 0, 0,
  3036. "The selected C++ Runtime Library is not supported by Ice; Ice requires /MD or /MDd.");
  3037. return false;
  3038. }
  3039. if(isWinRTProject(project))
  3040. {
  3041. return true;
  3042. }
  3043. //
  3044. // Ensure that linker settings match the Runtime Library settings.
  3045. //
  3046. ComponentList components = Util.getIceCppComponents(project);
  3047. bool debug = Util.isDebug(compilerTool.RuntimeLibrary);
  3048. string additionalDependencies = String.IsNullOrEmpty(linkerTool.AdditionalDependencies) ? "" : linkerTool.AdditionalDependencies;
  3049. //
  3050. // For each component we need to check that the correct
  3051. // library version (debug/release) is used.
  3052. //
  3053. foreach(string c in components)
  3054. {
  3055. string debugName = c + "d.lib";
  3056. string releaseName = c + ".lib";
  3057. if((debug && additionalDependencies.Contains(debugName)) ||
  3058. (!debug && additionalDependencies.Contains(releaseName)))
  3059. {
  3060. continue;
  3061. }
  3062. if(debug)
  3063. {
  3064. if(additionalDependencies.Contains(releaseName))
  3065. {
  3066. additionalDependencies = additionalDependencies.Replace(releaseName, debugName);
  3067. }
  3068. else
  3069. {
  3070. if(!String.IsNullOrEmpty(additionalDependencies) &&
  3071. !additionalDependencies.TrimEnd().EndsWith(";"))
  3072. {
  3073. additionalDependencies += ";";
  3074. }
  3075. additionalDependencies += debugName;
  3076. }
  3077. }
  3078. else
  3079. {
  3080. if(additionalDependencies.Contains(debugName))
  3081. {
  3082. additionalDependencies = additionalDependencies.Replace(debugName, releaseName);
  3083. }
  3084. else
  3085. {
  3086. if(!String.IsNullOrEmpty(additionalDependencies) &&
  3087. !additionalDependencies.TrimEnd().EndsWith(";"))
  3088. {
  3089. additionalDependencies += ";";
  3090. }
  3091. additionalDependencies += releaseName;
  3092. }
  3093. }
  3094. }
  3095. //
  3096. // If the linker settings has changed we update it.
  3097. //
  3098. if(!additionalDependencies.Equals(linkerTool.AdditionalDependencies))
  3099. {
  3100. linkerTool.AdditionalDependencies = additionalDependencies;
  3101. }
  3102. return true;
  3103. }
  3104. static public VCConfiguration getActiveVCConfiguration(Project project)
  3105. {
  3106. if(!Util.isCppProject(project))
  3107. {
  3108. return null;
  3109. }
  3110. ConfigurationManager configManager = project.ConfigurationManager;
  3111. if(configManager == null)
  3112. {
  3113. return null;
  3114. }
  3115. Configuration activeConfig;
  3116. try
  3117. {
  3118. activeConfig = (Configuration)configManager.ActiveConfiguration;
  3119. }
  3120. catch(COMException)
  3121. {
  3122. return null;
  3123. }
  3124. if(activeConfig == null)
  3125. {
  3126. return null;
  3127. }
  3128. VCProject vcProject = (VCProject)project.Object;
  3129. IVCCollection configurations = (IVCCollection)vcProject.Configurations;
  3130. VCConfiguration configuration = null;
  3131. foreach(VCConfiguration c in configurations)
  3132. {
  3133. if(c.Name != (activeConfig.ConfigurationName + "|" + activeConfig.PlatformName))
  3134. {
  3135. continue;
  3136. }
  3137. configuration = c;
  3138. break;
  3139. }
  3140. return configuration;
  3141. }
  3142. public static string projectFullName(Project p)
  3143. {
  3144. if(p.ParentProjectItem != null && p.ParentProjectItem.ContainingProject != null)
  3145. {
  3146. return projectFullName(p.ParentProjectItem.ContainingProject) + "/" + p.Name;
  3147. }
  3148. return p.Name;
  3149. }
  3150. public static string getTraceProjectName(Project project)
  3151. {
  3152. string fullName = projectFullName(project);
  3153. if(fullName.Equals(project.Name))
  3154. {
  3155. return fullName;
  3156. }
  3157. return project.Name + " (" + fullName + ")";
  3158. }
  3159. private static Command _refreshCommand;
  3160. public const string refreshCommandGUID = "{1496A755-94DE-11D0-8C3F-00C04FC2AAE2}";
  3161. public const string vsSmartDeviceCSharp = "{4D628B5B-2FBC-4AA6-8C16-197242AEB884}";
  3162. public const string vsSmartDeviceVB = "{68B1623D-7FB9-47D8-8664-7ECEA3297D4F}";
  3163. public const string unloadedProjectGUID = "{67294A52-A4F0-11D2-AA88-00C04F688DDE}";
  3164. public const int refreshCommandID = 222;
  3165. }
  3166. }