UNPKG

4.12 kBJavaScriptView Raw
1/**
2 * Detects if specific assemblies are installed.
3 *
4 * @module assemblies
5 *
6 * @copyright
7 * Copyright (c) 2014 by Appcelerator, Inc. All Rights Reserved.
8 *
9 * @license
10 * Licensed under the terms of the Apache Public License.
11 * Please see the LICENSE included with this distribution for details.
12 */
13
14const
15 appc = require('node-appc'),
16 fs = require('fs'),
17 magik = require('./utilities').magik,
18 path = require('path'),
19 __ = appc.i18n(__dirname).__;
20
21var cache;
22
23exports.detect = detect;
24
25/**
26 * Detects if specific assemblies are installed.
27 *
28 * @param {Object} [options] - An object containing various settings.
29 * @param {Boolean} [options.bypassCache=false] - When true, re-detects installed required assemblies.
30 * @param {String} [options.assemblyPath=%WINDIR%\Microsoft.NET\assembly\GAC_MSIL] - Path to .NET global assembly cache.
31 * @param {Object} [options.requiredAssemblies] - An object containing assemblies to check for in addition to the required windowslib dependencies.
32 * @param {Function} [callback(err, results)] - A function to call with the assembly information.
33 *
34 * @emits module:assemblies#detected
35 * @emits module:assemblies#error
36 *
37 * @returns {EventEmitter}
38 */
39function detect(options, callback) {
40 return magik(options, callback, function (emitter, options, callback) {
41 if (cache && !options.bypassCache) {
42 emitter.emit('detected', cache);
43 return callback(null, cache);
44 }
45
46 var requiredAssemblies = {
47 'Microsoft.SmartDevice.Connectivity.Interface': '>=10', // min version 10
48 'Microsoft.SmartDevice.MultiTargeting.Connectivity': '>=10' // min version 10
49 },
50 results = cache = {
51 assemblies: {},
52 issues: []
53 },
54 assemblyPath = appc.fs.resolvePath(options.assemblyPath || '%WINDIR%\\Microsoft.NET\\assembly\\GAC_MSIL');
55
56 Object.keys(requiredAssemblies).forEach(function (assembly) {
57 results.assemblies[assembly] = null;
58 });
59
60 if (options.requiredAssemblies !== null && typeof options.requiredAssemblies === 'object') {
61 Object.keys(options.requiredAssemblies).forEach(function (assembly) {
62 requiredAssemblies[assembly] = options.requiredAssemblies[assembly];
63 results.assemblies[assembly] = null;
64 });
65 }
66
67 if (!fs.existsSync(assemblyPath)) {
68 results.issues.push({
69 id: 'WINDOWS_GAC_PATH_DOES_NOT_EXIST',
70 type: 'error',
71 message: __('The Microsoft.NET global assembly cache path "%s" does not exist.', assemblyPath)
72 });
73
74 process.nextTick(function () {
75 emitter.emit('detected', cache);
76 callback(null, cache);
77 });
78 } else {
79 // example value: "v4.0_11.0.1__b03f5f7f11d50a3a"
80 var assemblyVersionRegExp = /^v?((?:(?:\d\.)?\d\.)?\d)_((?:(?:(?:\d+\.)?\d+\.)?\d+\.)?\d+).*_+(.*)$/,
81 missingAssemblies = [];
82
83 Object.keys(requiredAssemblies).forEach(function (assembly) {
84 var dir = path.join(assemblyPath, assembly);
85 if (fs.existsSync(dir))
86 {
87 fs.readdirSync(dir).forEach(function (name) {
88 var m = name.match(assemblyVersionRegExp),
89 file = m && path.join(dir, name, assembly + '.dll');
90
91 if (m && m[2] && (!requiredAssemblies[assembly] || appc.version.satisfies(m[2], requiredAssemblies[assembly]), true) && fs.existsSync(file)) {
92 results.assemblies[assembly] || (results.assemblies[assembly] = {});
93 results.assemblies[assembly][m[2]] = {
94 assemblyFile: file,
95 dotNetVersion: m[1],
96 assemblyVersion: m[2],
97 publicKeyToken: m[3]
98 };
99 }
100 });
101 }
102
103 if (!results.assemblies[assembly]) {
104 missingAssemblies.push(assembly);
105 }
106 });
107
108 if (missingAssemblies.length) {
109 results.issues.push({
110 id: 'WINDOWS_MISSING_REQUIRED_ASSEMBLIES',
111 type: 'error',
112 message: __('Unable to find the following required Microsoft.NET assemblies: %s.', '"' + missingAssemblies.join('", "') + '"') + '\n' +
113 __('These should be resolved by reinstalling Microsoft Visual Studio.')
114 });
115 }
116
117 emitter.emit('detected', results);
118 callback(null, results);
119 }
120 });
121};