forked from paulj/webgac
/
AddWebGACAssemblySearchPaths.cs
133 lines (117 loc) · 4.4 KB
/
AddWebGACAssemblySearchPaths.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using WebGAC.Core;
namespace WebGAC.MSBuild {
/// <summary>
/// Adds WebGAC folders to the assembly search path for any WebGAC references.
/// </summary>
public class AddWebGACAssemblySearchPaths : Task {
/// <summary>
/// String used in the AssemblySearchPath property to specify where
/// WebGAC folder items should be added.
/// </summary>
public const string WebGACSearchPathIndicator = "{WebGAC}";
private string[] mPaths;
private ITaskItem[] mAssemblies;
private string mPrimaryConfiguration;
private string mAllConfigurationsStr;
private string[] mAllConfigurations;
private readonly WebGAC.Core.WebGAC mGac;
public AddWebGACAssemblySearchPaths() {
mGac = WebGACFactory.WebGAC;
}
/// <summary>
/// Gets or sets the Mono assembly search paths.
/// </summary>
[Required]
[Output]
public string[] Paths {
get { return mPaths; }
set { mPaths = value; }
}
/// <summary>
/// These are the assembly references in the project being built. This
/// set of items is also passed to the ResolveAssemblyReference task.
/// </summary>
[Required]
public ITaskItem[] Assemblies {
get { return mAssemblies; }
set { mAssemblies = value; }
}
/// <summary>
/// The current build configuration.
/// </summary>
public string PrimaryConfiguration {
get { return mPrimaryConfiguration; }
set { mPrimaryConfiguration = value; }
}
/// <summary>
/// The list of all available configurations.
/// </summary>
[Required]
public string AllConfigurations {
get { return mAllConfigurationsStr; }
set {
mAllConfigurationsStr = value;
mAllConfigurations = value.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
}
}
/// <summary>
/// Replaces the {WebGAC} entry in the AssemblySearchPaths.
/// </summary>
public override bool Execute() {
List<string> updatedSearchPaths = new List<string>();
IDictionary<string, object> webGACSearchPaths = new Dictionary<string, object>();
// Default the primary configuration if it hasn't been set
if (mPrimaryConfiguration == null) {
mPrimaryConfiguration = mAllConfigurations[0];
}
if (mAssemblies != null) {
foreach (ITaskItem item in mAssemblies) {
try {
string path = mGac.Resolve(item.ItemSpec, mPrimaryConfiguration, mAllConfigurations);
if (path != null) {
string directoryName = Path.GetDirectoryName(path);
if (!webGACSearchPaths.ContainsKey(directoryName)) {
webGACSearchPaths.Add(directoryName, null);
// We also need to check for dependencies
BuildPathsForAssembly(path, webGACSearchPaths);
}
}
} catch (Exception ex) {
Log.LogErrorFromException(ex);
}
}
}
// Add WebGAC search paths to existing search paths.
foreach (string path in mPaths) {
if (path.Equals(WebGACSearchPathIndicator, StringComparison.InvariantCultureIgnoreCase)) {
updatedSearchPaths.AddRange(webGACSearchPaths.Keys);
} else {
updatedSearchPaths.Add(path);
}
}
mPaths = updatedSearchPaths.ToArray();
return true;
}
private void BuildPathsForAssembly(string pPath, IDictionary<string, object> pPaths) {
Log.LogMessage(MessageImportance.Low, "About to load " + pPath);
Assembly assembly = Assembly.LoadFrom(pPath);
AssemblyName[] names = assembly.GetReferencedAssemblies();
foreach (AssemblyName name in names) {
string referencedPath = mGac.Resolve(name.Name, name.Version, null, null, mPrimaryConfiguration, mAllConfigurations); // TODO: Add other fields if needed later
if (referencedPath != null) {
string directoryName = Path.GetDirectoryName(referencedPath);
if (!pPaths.ContainsKey(directoryName)) {
pPaths.Add(directoryName, null);
BuildPathsForAssembly(referencedPath, pPaths);
}
}
}
}
}
}