forked from madrang/MFDebugger-Mono
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGetDeviceFrameworkPath.cs
350 lines (291 loc) · 15.1 KB
/
GetDeviceFrameworkPath.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
// NOTE: this was copied from the BuildTasks (NativeBuildTasks) project; if we port BuildTasks then we should re-reference that project instead of including this here.
#region Using directives
using System;
using System.IO;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.Win32;
using System.Diagnostics;
#endregion
namespace Microsoft.SPOT.Tasks
{
public sealed class GetDeviceFrameworkPaths : Task
{
internal class RegistryValues
{
public const string Default = "";
public const string FrameworkRegistryBase = @"Software\Microsoft\.NETMicroFramework";
public const string FrameworkRegistryBase32 = @"Software\Wow6432Node\Microsoft\.NETMicroFramework";
public const string InstallRoot = "InstallRoot";
}
public class Directories
{
public const string Tools = "Tools";
public const string Assemblies = "Assemblies";
}
class RegistryKeys
{
public const string AssemblyFoldersEx = "AssemblyFoldersEx";
}
internal class MfSdkInternalError : Exception
{
public MfSdkInternalError(string errMsg)
: base("MF SDK internal error: " + errMsg + "; this MF SDK installation is not valid.")
{
}
}
#region Properties
private string runtimeVersion = null;
private string toolsPath;
private string frameworkAssembliesPath, frameworkAssembliesPathLE, frameworkAssembliesPathBE;
private string installRoot;
public string RuntimeVersion
{
get { return runtimeVersion; }
set { runtimeVersion = value; }
}
[Output]
public string FrameworkAssembliesPath
{
get { return frameworkAssembliesPath; }
set { frameworkAssembliesPath = value; }
}
[Output]
public string FrameworkAssembliesPathLE
{
get { return frameworkAssembliesPathLE; }
set { frameworkAssembliesPathLE = value; }
}
[Output]
public string FrameworkAssembliesPathBE
{
get { return frameworkAssembliesPathBE; }
set { frameworkAssembliesPathBE = value; }
}
[Output]
public string ToolsPath
{
get { return toolsPath; }
set { toolsPath = value; }
}
[Output]
public string InstallRoot
{
get { return installRoot; }
set { installRoot = value; }
}
#endregion
#region ITask Members
// NOTE: this is temporary code, for compatibility with .NET 3.5; it is currently untested.
private Version ParseVersion(string version)
{
int majorVersion = 0;
int minorVersion = 0;
string versionString = version;
if (versionString.IndexOf('.') >= 0)
{
majorVersion = int.Parse(versionString.Substring(0, versionString.IndexOf('.')));
versionString = versionString.Substring(versionString.IndexOf('.') + 1);
if (versionString.IndexOf('.') >= 0)
{
minorVersion = int.Parse(versionString.Substring(0, versionString.IndexOf('.')));
}
else
{
minorVersion = int.Parse(versionString);
}
}
return new Version(majorVersion, minorVersion);
}
public override bool Execute()
{
try
{
if (!string.IsNullOrEmpty(runtimeVersion) && !runtimeVersion.StartsWith("v"))
throw new MfSdkInternalError(String.Format("runtimeVersion string \"{0}\" is malformed", runtimeVersion));
string build_root = Environment.GetEnvironmentVariable("BUILD_ROOT");
if (!string.IsNullOrEmpty(runtimeVersion))
{
//Version ver = Version.Parse(runtimeVersion.TrimStart('v'));
Version ver = ParseVersion(runtimeVersion.TrimStart('v'));
installRoot = GetDeviceFrameworkValue("v" + ver.ToString(2), null, RegistryValues.InstallRoot);
}
if (installRoot == null || !Directory.Exists(installRoot) || 0 == string.Compare(Path.GetDirectoryName(Path.GetDirectoryName(installRoot)), Path.GetDirectoryName(build_root), true))
{
// If there is no install-root value, perhaps it's because this is an internal development build.
// The SPOCLIENT environment variable should name a valid directory, and BUILD_TREE_CLIENT & BUILD_TREE_SERVER as well.
// Otherwise, it really is a broken installation
string spoclient = Environment.GetEnvironmentVariable(@"SPOCLIENT");
string build_tree_client = Environment.GetEnvironmentVariable(@"BUILD_TREE_CLIENT");
string build_tree_server = Environment.GetEnvironmentVariable(@"BUILD_TREE_SERVER");
if (String.IsNullOrEmpty(spoclient) || String.IsNullOrEmpty(build_tree_client) || String.IsNullOrEmpty(build_tree_server))
{
throw new MfSdkInternalError("The MF SDK does not appear to be available on this machine");
}
installRoot = build_tree_client;
toolsPath = Path.Combine(build_tree_server, @"DLL");
frameworkAssembliesPath = Path.Combine(build_tree_client, @"DLL");
frameworkAssembliesPathLE = frameworkAssembliesPath;
frameworkAssembliesPathBE = frameworkAssembliesPath;
}
else
{
toolsPath = Path.Combine(installRoot, Directories.Tools);
// Check the AssemblyFolder subkey; this is used only internally to support the mfpseudoinstaller style of running MF SDK;
// not needed by the PK or by a real, installed, MF SDK. Not externally documented or supported.
frameworkAssembliesPath = GetDeviceFrameworkValue(runtimeVersion, "AssemblyFolder", RegistryValues.Default);
if (!string.IsNullOrEmpty(frameworkAssembliesPath))
{
if (!Directory.Exists(frameworkAssembliesPath))
{
Log.LogWarning("The directory \"{0}\" named by the AssemblyFolder key does not exist", frameworkAssembliesPath);
frameworkAssembliesPath = null;
}
}
frameworkAssembliesPath = Path.Combine(installRoot, Directories.Assemblies);
if (Directory.Exists(Path.Combine(frameworkAssembliesPath, "be")))
{
frameworkAssembliesPathLE = Path.Combine(frameworkAssembliesPath, "le");
frameworkAssembliesPathBE = Path.Combine(frameworkAssembliesPath, "be");
frameworkAssembliesPath = frameworkAssembliesPathLE;
}
else
{
frameworkAssembliesPathLE = frameworkAssembliesPath;
frameworkAssembliesPathBE = frameworkAssembliesPath;
}
FileInfo mscorlibLEInfo = new FileInfo(Path.Combine(frameworkAssembliesPathLE, @"mscorlib.dll"));
FileInfo mscorlibBEInfo = new FileInfo(Path.Combine(frameworkAssembliesPathBE, @"mscorlib.dll"));
FileInfo metadataProcessorInfo = new FileInfo(Path.Combine(toolsPath, @"MetadataProcessor.exe"));
if (!Directory.Exists(toolsPath) || !metadataProcessorInfo.Exists)
throw new MfSdkInternalError(String.Format("The directory \"{0}\" that should contain the MF SDK toolchain does not exist or is not fully installed", toolsPath));
if (!Directory.Exists(frameworkAssembliesPathLE) || !mscorlibLEInfo.Exists)
throw new MfSdkInternalError(String.Format("The directory \"{0}\" that should contain the MF SDK assemblies does not exist or is not fully installed", frameworkAssembliesPathLE));
if (!Directory.Exists(frameworkAssembliesPathBE) || !mscorlibBEInfo.Exists)
throw new MfSdkInternalError(String.Format("The directory \"{0}\" that should contain the MF SDK assemblies does not exist or is not fully installed", frameworkAssembliesPathBE));
}
return true;
}
catch (Exception ex)
{
try
{
Log.LogErrorFromException(ex);
}
catch { }
}
return false;
}
#endregion
// This method by design does not catch any exceptions; it is intended only to be called by
// public methods of this class, which ought necessarily to be handling their exceptions anyway.
private static string GetDeviceFrameworkValue(string runtimeVersion, string subkey, string valueName)
{
// Look in HKCU first for the value
string valueStr = GetDeviceFrameworkValue(Registry.CurrentUser, runtimeVersion, subkey, valueName);
if (valueStr != null)
return valueStr;
// Not there? try HKLM
return GetDeviceFrameworkValue(Registry.LocalMachine, runtimeVersion, subkey, valueName);
}
// This private method by design does not catch any exceptions; it is intended only to be called by
// public methods of this class, which ought necessarily to be handling their exceptions anyway.
private static string GetDeviceFrameworkValue(RegistryKey topLevelKey, string runtimeVersion, string subkey, string valueName)
{
object value = null;
RegistryKey key = OpenDeviceFrameworkKey(topLevelKey, runtimeVersion, subkey);
if (key != null && (value = key.GetValue(valueName)) != null)
{
if (value is String)
{
return value as String;
}
else
{
throw new MfSdkInternalError(String.Format("The value of \"{0}\" at key \"{1}\" was not of type string", valueName, key.Name));
}
}
return null;
}
public static string GetDeviceFrameworkValueOrThrow(string runtimeVersion, string subkey, string valueName)
{
string value = GetDeviceFrameworkValue(runtimeVersion, subkey, valueName);
if (value == null)
{
throw new MfSdkInternalError(
runtimeVersion == null
? String.Format("\"{0}\" registry value not present at key \"{1}\" in the most recent version", valueName, subkey)
: String.Format("\"{0}\" registry value not present at key \"{1}\" for runtime version {2}", valueName, subkey, runtimeVersion)
);
}
return value;
}
public static RegistryKey OpenDeviceFrameworkKey(RegistryKey topLevelKey, string runtimeVersion, string subkey)
{
RegistryKey retVal = OpenDeviceFrameworkKey(topLevelKey, runtimeVersion, subkey, false);
if (retVal == null)
{
retVal = OpenDeviceFrameworkKey(topLevelKey, runtimeVersion, subkey, true);
}
return retVal;
}
internal static RegistryKey OpenDeviceFrameworkKey(RegistryKey topLevelKey, string runtimeVersion, string subkey, bool fWow64)
{
if (runtimeVersion == null)
{
// attempt to get the 'Product' version of the current executing assembly first;
// by convention we use the InformationalVersion attribute as the Product version
System.Reflection.AssemblyInformationalVersionAttribute[] myInformationalVersionAttributes
= (System.Reflection.AssemblyInformationalVersionAttribute[])System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(System.Reflection.AssemblyInformationalVersionAttribute), false);
if (null != myInformationalVersionAttributes && myInformationalVersionAttributes.Length > 0)
{
string[] verParts = myInformationalVersionAttributes[0].InformationalVersion.Split(new Char[] { '.' });
if (verParts == null || verParts.Length == 0)
runtimeVersion = "v4.1";
else if (verParts.Length == 1)
runtimeVersion = String.Format("v{0}.0", verParts[0]);
else
runtimeVersion = String.Format("v{0}.{1}", verParts[0], verParts[1]);
}
}
if (runtimeVersion == null)
{
// Fall back to using the version of this individual assembly if the product-wide version is not present
Version myVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
runtimeVersion = String.Format("v{0}.{1}", myVersion.Major, myVersion.Minor);
}
//call dispose on all these open keys?
string frameworkRegistryBase = fWow64 ? RegistryValues.FrameworkRegistryBase32 : RegistryValues.FrameworkRegistryBase;
// Find registry location
RegistryKey hiveroot = topLevelKey.OpenSubKey(frameworkRegistryBase);
if (hiveroot == null)
return null;
// Find latest version
string version = "v0";
RegistryKey vKey = null;
RegistryKey key = null;
foreach (string subkeyname in hiveroot.GetSubKeyNames())
{
if (runtimeVersion != null && subkeyname.Length < runtimeVersion.Length)
continue;
if (runtimeVersion == null || subkeyname.Substring(0, runtimeVersion.Length) == runtimeVersion)
{
if ((key = hiveroot.OpenSubKey(subkeyname)) == null)
continue;
if (subkey != null && subkey.Length > 0)
{
if ((key = key.OpenSubKey(subkey)) == null)
continue;
}
if (key != null && String.Compare(subkeyname, version) > 0)
{
version = subkeyname;
vKey = key;
}
}
}
return vKey;
}
}
}