OLD | NEW |
| (Empty) |
1 /// Copyright (c) Microsoft Corporation. All rights reserved. | |
2 | |
3 using System; | |
4 using System.Collections; | |
5 using System.Collections.Generic; | |
6 using System.Diagnostics; | |
7 using System.Diagnostics.CodeAnalysis; | |
8 using System.Globalization; | |
9 using System.IO; | |
10 using System.Runtime.InteropServices; | |
11 using Microsoft.VisualStudio; | |
12 using Microsoft.VisualStudio.Shell; | |
13 using Microsoft.VisualStudio.Shell.Interop; | |
14 using MSBuild = Microsoft.Build.BuildEngine; | |
15 | |
16 /* This file provides a basefunctionallity for IVsCfgProvider2. | |
17 Instead of using the IVsProjectCfgEventsHelper object we have our own little
sink and call our own helper methods | |
18 similiar to the interface. But there is no real benefit in inheriting from th
e interface in the first place. | |
19 Using the helper object seems to be: | |
20 a) undocumented | |
21 b) not really wise in the managed world | |
22 */ | |
23 namespace Microsoft.VisualStudio.Project | |
24 { | |
25 [CLSCompliant(false)] | |
26 [ComVisible(true)] | |
27 public class ConfigProvider : IVsCfgProvider2, IVsProjectCfgProvider, IV
sExtensibleObject | |
28 { | |
29 #region fields | |
30 internal const string configString = " '$(Configuration)' == '{0
}' "; | |
31 internal const string AnyCPUPlatform = "Any CPU"; | |
32 | |
33 private ProjectNode project; | |
34 private EventSinkCollection cfgEventSinks = new EventSinkCollect
ion(); | |
35 private List<KeyValuePair<KeyValuePair<string, string>, string>>
newCfgProps = new List<KeyValuePair<KeyValuePair<string, string>, string>>(); | |
36 private Dictionary<string, ProjectConfig> configurationsList = n
ew Dictionary<string, ProjectConfig>(); | |
37 #endregion | |
38 | |
39 #region Properties | |
40 /// <summary> | |
41 /// The associated project. | |
42 /// </summary> | |
43 protected ProjectNode ProjectMgr | |
44 { | |
45 get | |
46 { | |
47 return this.project; | |
48 } | |
49 } | |
50 /// <summary> | |
51 /// If the project system wants to add custom properties to the
property group then | |
52 /// they provide us with this data. | |
53 /// Returns/sets the [(<propName, propCondition>) <propValue>] c
ollection | |
54 /// </summary> | |
55 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Desi
gn", "CA1002:DoNotExposeGenericLists"), System.Diagnostics.CodeAnalysis.Suppress
Message("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] | |
56 public virtual List<KeyValuePair<KeyValuePair<string, string>, s
tring>> NewConfigProperties | |
57 { | |
58 get | |
59 { | |
60 return newCfgProps; | |
61 } | |
62 set | |
63 { | |
64 newCfgProps = value; | |
65 } | |
66 } | |
67 | |
68 #endregion | |
69 | |
70 #region ctors | |
71 public ConfigProvider(ProjectNode manager) | |
72 { | |
73 this.project = manager; | |
74 } | |
75 #endregion | |
76 | |
77 #region methods | |
78 /// <summary> | |
79 /// Creates new Project Configuartion objects based on the confi
guration name. | |
80 /// </summary> | |
81 /// <param name="configName">The name of the configuration</para
m> | |
82 /// <returns>An instance of a ProjectConfig object.</returns> | |
83 protected ProjectConfig GetProjectConfiguration(string configNam
e) | |
84 { | |
85 // if we already created it, return the cached one | |
86 if(configurationsList.ContainsKey(configName)) | |
87 { | |
88 return configurationsList[configName]; | |
89 } | |
90 | |
91 ProjectConfig requestedConfiguration = CreateProjectConf
iguration(configName); | |
92 configurationsList.Add(configName, requestedConfiguratio
n); | |
93 | |
94 return requestedConfiguration; | |
95 } | |
96 | |
97 protected virtual ProjectConfig CreateProjectConfiguration(strin
g configName) | |
98 { | |
99 return new ProjectConfig(this.project, configName); | |
100 } | |
101 | |
102 #endregion | |
103 | |
104 #region IVsProjectCfgProvider methods | |
105 /// <summary> | |
106 /// Provides access to the IVsProjectCfg interface implemented o
n a project's configuration object. | |
107 /// </summary> | |
108 /// <param name="projectCfgCanonicalName">The canonical name of
the configuration to access.</param> | |
109 /// <param name="projectCfg">The IVsProjectCfg interface of the
configuration identified by szProjectCfgCanonicalName.</param> | |
110 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code. </returns> | |
111 public virtual int OpenProjectCfg(string projectCfgCanonicalName
, out IVsProjectCfg projectCfg) | |
112 { | |
113 if(projectCfgCanonicalName == null) | |
114 { | |
115 throw new ArgumentNullException("projectCfgCanon
icalName"); | |
116 } | |
117 | |
118 projectCfg = null; | |
119 | |
120 // Be robust in release | |
121 if(projectCfgCanonicalName == null) | |
122 { | |
123 return VSConstants.E_INVALIDARG; | |
124 } | |
125 | |
126 | |
127 Debug.Assert(this.project != null && this.project.BuildP
roject != null); | |
128 | |
129 string[] configs = this.project.BuildProject.GetConditio
nedPropertyValues(ProjectFileConstants.Configuration); | |
130 | |
131 | |
132 foreach(string config in configs) | |
133 { | |
134 if(String.Compare(config, projectCfgCanonicalNam
e, StringComparison.OrdinalIgnoreCase) == 0) | |
135 { | |
136 projectCfg = this.GetProjectConfiguratio
n(config); | |
137 if(projectCfg != null) | |
138 { | |
139 return VSConstants.S_OK; | |
140 } | |
141 else | |
142 { | |
143 return VSConstants.E_FAIL; | |
144 } | |
145 } | |
146 } | |
147 | |
148 return VSConstants.E_INVALIDARG; | |
149 } | |
150 | |
151 /// <summary> | |
152 /// Checks whether or not this configuration provider uses indep
endent configurations. | |
153 /// </summary> | |
154 /// <param name="usesIndependentConfigurations">true if independ
ent configurations are used, false if they are not used. By default returns true
.</param> | |
155 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
156 public virtual int get_UsesIndependentConfigurations(out int use
sIndependentConfigurations) | |
157 { | |
158 usesIndependentConfigurations = 1; | |
159 return VSConstants.S_OK; | |
160 } | |
161 #endregion | |
162 | |
163 #region IVsCfgProvider2 methods | |
164 /// <summary> | |
165 /// Copies an existing configuration name or creates a new one. | |
166 /// </summary> | |
167 /// <param name="name">The name of the new configuration.</param
> | |
168 /// <param name="cloneName">the name of the configuration to cop
y, or a null reference, indicating that AddCfgsOfCfgName should create a new con
figuration.</param> | |
169 /// <param name="fPrivate">Flag indicating whether or not the ne
w configuration is private. If fPrivate is set to true, the configuration is pri
vate. If set to false, the configuration is public. This flag can be ignored.</p
aram> | |
170 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code. </returns> | |
171 public virtual int AddCfgsOfCfgName(string name, string cloneNam
e, int fPrivate) | |
172 { | |
173 // We need to QE/QS the project file | |
174 if(!this.ProjectMgr.QueryEditProjectFile(false)) | |
175 { | |
176 throw Marshal.GetExceptionForHR(VSConstants.OLE_
E_PROMPTSAVECANCELLED); | |
177 } | |
178 | |
179 // First create the condition that represent the configu
ration we want to clone | |
180 string condition = (cloneName == null ? String.Empty : S
tring.Format(CultureInfo.InvariantCulture, configString, cloneName).Trim()); | |
181 | |
182 // Get all configs | |
183 MSBuild.BuildPropertyGroupCollection configGroup = this.
project.BuildProject.PropertyGroups; | |
184 MSBuild.BuildPropertyGroup configToClone = null; | |
185 | |
186 if(cloneName != null) | |
187 { | |
188 // Find the configuration to clone | |
189 foreach(MSBuild.BuildPropertyGroup currentConfig
in configGroup) | |
190 { | |
191 // Only care about conditional property
groups | |
192 if(currentConfig.Condition == null || cu
rrentConfig.Condition.Length == 0) | |
193 continue; | |
194 | |
195 // Skip if it isn't the group we want | |
196 if(String.Compare(currentConfig.Conditio
n.Trim(), condition, StringComparison.OrdinalIgnoreCase) != 0) | |
197 continue; | |
198 | |
199 configToClone = currentConfig; | |
200 } | |
201 } | |
202 | |
203 MSBuild.BuildPropertyGroup newConfig = null; | |
204 if(configToClone != null) | |
205 { | |
206 // Clone the configuration settings | |
207 newConfig = this.project.ClonePropertyGroup(conf
igToClone); | |
208 //Will be added later with the new values to the
path | |
209 newConfig.RemoveProperty("OutputPath"); | |
210 } | |
211 else | |
212 { | |
213 // no source to clone from, lets just create a n
ew empty config | |
214 newConfig = this.project.BuildProject.AddNewProp
ertyGroup(false); | |
215 // Get the list of property name, condition valu
e from the config provider | |
216 IList<KeyValuePair<KeyValuePair<string, string>,
string>> propVals = this.NewConfigProperties; | |
217 foreach(KeyValuePair<KeyValuePair<string, string
>, string> data in propVals) | |
218 { | |
219 KeyValuePair<string, string> propData =
data.Key; | |
220 string value = data.Value; | |
221 MSBuild.BuildProperty newProperty = newC
onfig.AddNewProperty(propData.Key, value); | |
222 if(!String.IsNullOrEmpty(propData.Value)
) | |
223 newProperty.Condition = propData
.Value; | |
224 } | |
225 } | |
226 | |
227 | |
228 //add the output path | |
229 string outputBasePath = this.ProjectMgr.OutputBaseRelati
vePath; | |
230 if(outputBasePath.EndsWith(Path.DirectorySeparatorChar.T
oString(), StringComparison.Ordinal)) | |
231 outputBasePath = Path.GetDirectoryName(outputBas
ePath); | |
232 newConfig.AddNewProperty("OutputPath", Path.Combine(outp
utBasePath, name) + Path.DirectorySeparatorChar.ToString()); | |
233 | |
234 // Set the condition that will define the new configurat
ion | |
235 string newCondition = String.Format(CultureInfo.Invarian
tCulture, configString, name); | |
236 newConfig.Condition = newCondition; | |
237 | |
238 NotifyOnCfgNameAdded(name); | |
239 return VSConstants.S_OK; | |
240 } | |
241 | |
242 /// <summary> | |
243 /// Copies an existing platform name or creates a new one. | |
244 /// </summary> | |
245 /// <param name="platformName">The name of the new platform.</pa
ram> | |
246 /// <param name="clonePlatformName">The name of the platform to
copy, or a null reference, indicating that AddCfgsOfPlatformName should create a
new platform.</param> | |
247 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
248 public virtual int AddCfgsOfPlatformName(string platformName, st
ring clonePlatformName) | |
249 { | |
250 return VSConstants.E_NOTIMPL; | |
251 } | |
252 | |
253 /// <summary> | |
254 /// Deletes a specified configuration name. | |
255 /// </summary> | |
256 /// <param name="name">The name of the configuration to be delet
ed.</param> | |
257 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code. </returns> | |
258 public virtual int DeleteCfgsOfCfgName(string name) | |
259 { | |
260 // We need to QE/QS the project file | |
261 if(!this.ProjectMgr.QueryEditProjectFile(false)) | |
262 { | |
263 throw Marshal.GetExceptionForHR(VSConstants.OLE_
E_PROMPTSAVECANCELLED); | |
264 } | |
265 | |
266 if(name == null) | |
267 { | |
268 Debug.Fail(String.Format(CultureInfo.CurrentCult
ure, "Name of the configuration should not be null if you want to delete it from
project: {0}", this.project.BuildProject.FullFileName)); | |
269 // The configuration " '$(Configuration)' == "
does not exist, so technically the goal | |
270 // is achieved so return S_OK | |
271 return VSConstants.S_OK; | |
272 } | |
273 // Verify that this config exist | |
274 string[] configs = this.project.BuildProject.GetConditio
nedPropertyValues(ProjectFileConstants.Configuration); | |
275 foreach(string config in configs) | |
276 { | |
277 if(String.Compare(config, name, StringComparison
.OrdinalIgnoreCase) == 0) | |
278 { | |
279 // Create condition of config to remove | |
280 string condition = String.Format(Culture
Info.InvariantCulture, configString, config); | |
281 this.project.BuildProject.RemoveProperty
GroupsWithMatchingCondition(condition); | |
282 | |
283 NotifyOnCfgNameDeleted(name); | |
284 } | |
285 } | |
286 | |
287 return VSConstants.S_OK; | |
288 } | |
289 | |
290 /// <summary> | |
291 /// Deletes a specified platform name. | |
292 /// </summary> | |
293 /// <param name="platName">The platform name to delet.</param> | |
294 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
295 public virtual int DeleteCfgsOfPlatformName(string platName) | |
296 { | |
297 return VSConstants.E_NOTIMPL; | |
298 } | |
299 | |
300 /// <summary> | |
301 /// Returns the existing configurations stored in the project fi
le. | |
302 /// </summary> | |
303 /// <param name="celt">Specifies the requested number of propert
y names. If this number is unknown, celt can be zero.</param> | |
304 /// <param name="names">On input, an allocated array to hold the
number of configuration property names specified by celt. This parameter can al
so be a null reference if the celt parameter is zero. | |
305 /// On output, names contains configuration property names.</par
am> | |
306 /// <param name="actual">The actual number of property names ret
urned.</param> | |
307 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
308 public virtual int GetCfgNames(uint celt, string[] names, uint[]
actual) | |
309 { | |
310 // get's called twice, once for allocation, then for ret
rieval | |
311 int i = 0; | |
312 | |
313 string[] configList = this.project.BuildProject.GetCondi
tionedPropertyValues(ProjectFileConstants.Configuration); | |
314 | |
315 if(names != null) | |
316 { | |
317 foreach(string config in configList) | |
318 { | |
319 names[i++] = config; | |
320 if(i == celt) | |
321 break; | |
322 } | |
323 } | |
324 else | |
325 i = configList.Length; | |
326 | |
327 if(actual != null) | |
328 { | |
329 actual[0] = (uint)i; | |
330 } | |
331 | |
332 return VSConstants.S_OK; | |
333 } | |
334 | |
335 /// <summary> | |
336 /// Returns the configuration associated with a specified config
uration or platform name. | |
337 /// </summary> | |
338 /// <param name="name">The name of the configuration to be retur
ned.</param> | |
339 /// <param name="platName">The name of the platform for the conf
iguration to be returned.</param> | |
340 /// <param name="cfg">The implementation of the IVsCfg interface
.</param> | |
341 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
342 public virtual int GetCfgOfName(string name, string platName, ou
t IVsCfg cfg) | |
343 { | |
344 cfg = null; | |
345 cfg = this.GetProjectConfiguration(name); | |
346 | |
347 return VSConstants.S_OK; | |
348 } | |
349 | |
350 /// <summary> | |
351 /// Returns a specified configuration property. | |
352 /// </summary> | |
353 /// <param name="propid">Specifies the property identifier for t
he property to return. For valid propid values, see __VSCFGPROPID.</param> | |
354 /// <param name="var">The value of the property.</param> | |
355 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
356 public virtual int GetCfgProviderProperty(int propid, out object
var) | |
357 { | |
358 var = false; | |
359 switch((__VSCFGPROPID)propid) | |
360 { | |
361 case __VSCFGPROPID.VSCFGPROPID_SupportsCfgAdd: | |
362 var = true; | |
363 break; | |
364 | |
365 case __VSCFGPROPID.VSCFGPROPID_SupportsCfgDelete
: | |
366 var = true; | |
367 break; | |
368 | |
369 case __VSCFGPROPID.VSCFGPROPID_SupportsCfgRename
: | |
370 var = true; | |
371 break; | |
372 | |
373 case __VSCFGPROPID.VSCFGPROPID_SupportsPlatformA
dd: | |
374 var = false; | |
375 break; | |
376 | |
377 case __VSCFGPROPID.VSCFGPROPID_SupportsPlatformD
elete: | |
378 var = false; | |
379 break; | |
380 } | |
381 return VSConstants.S_OK; | |
382 } | |
383 | |
384 /// <summary> | |
385 /// Returns the per-configuration objects for this object. | |
386 /// </summary> | |
387 /// <param name="celt">Number of configuration objects to be ret
urned or zero, indicating a request for an unknown number of objects.</param> | |
388 /// <param name="a">On input, pointer to an interface array or a
null reference. On output, this parameter points to an array of IVsCfg interfac
es belonging to the requested configuration objects.</param> | |
389 /// <param name="actual">The number of configuration objects act
ually returned or a null reference, if this information is not necessary.</param
> | |
390 /// <param name="flags">Flags that specify settings for project
configurations, or a null reference (Nothing in Visual Basic) if no additional f
lag settings are required. For valid prgrFlags values, see __VSCFGFLAGS.</param> | |
391 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
392 public virtual int GetCfgs(uint celt, IVsCfg[] a, uint[] actual,
uint[] flags) | |
393 { | |
394 if(flags != null) | |
395 flags[0] = 0; | |
396 | |
397 int i = 0; | |
398 string[] configList = this.project.BuildProject.GetCondi
tionedPropertyValues(ProjectFileConstants.Configuration); | |
399 | |
400 if(a != null) | |
401 { | |
402 foreach(string configName in configList) | |
403 { | |
404 a[i] = this.GetProjectConfiguration(conf
igName); | |
405 | |
406 i++; | |
407 if(i == celt) | |
408 break; | |
409 } | |
410 } | |
411 else | |
412 i = configList.Length; | |
413 | |
414 if(actual != null) | |
415 actual[0] = (uint)i; | |
416 | |
417 return VSConstants.S_OK; | |
418 } | |
419 | |
420 /// <summary> | |
421 /// Returns one or more platform names. | |
422 /// </summary> | |
423 /// <param name="celt">Specifies the requested number of platfor
m names. If this number is unknown, celt can be zero.</param> | |
424 /// <param name="names">On input, an allocated array to hold the
number of platform names specified by celt. This parameter can also be a null r
eference if the celt parameter is zero. On output, names contains platform names
.</param> | |
425 /// <param name="actual">The actual number of platform names ret
urned.</param> | |
426 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
427 public virtual int GetPlatformNames(uint celt, string[] names, u
int[] actual) | |
428 { | |
429 string[] platforms = this.GetPlatformsFromProject(); | |
430 return GetPlatforms(celt, names, actual, platforms); | |
431 } | |
432 | |
433 /// <summary> | |
434 /// Returns the set of platforms that are installed on the user'
s machine. | |
435 /// </summary> | |
436 /// <param name="celt">Specifies the requested number of support
ed platform names. If this number is unknown, celt can be zero.</param> | |
437 /// <param name="names">On input, an allocated array to hold the
number of names specified by celt. This parameter can also be a null reference
(Nothing in Visual Basic)if the celt parameter is zero. On output, names contain
s the names of supported platforms</param> | |
438 /// <param name="actual">The actual number of platform names ret
urned.</param> | |
439 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
440 public virtual int GetSupportedPlatformNames(uint celt, string[]
names, uint[] actual) | |
441 { | |
442 string[] platforms = this.GetSupportedPlatformsFromProje
ct(); | |
443 return GetPlatforms(celt, names, actual, platforms); | |
444 } | |
445 | |
446 /// <summary> | |
447 /// Assigns a new name to a configuration. | |
448 /// </summary> | |
449 /// <param name="old">The old name of the target configuration.<
/param> | |
450 /// <param name="newname">The new name of the target configurati
on.</param> | |
451 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
452 public virtual int RenameCfgsOfCfgName(string old, string newnam
e) | |
453 { | |
454 // First create the condition that represent the configu
ration we want to rename | |
455 string condition = String.Format(CultureInfo.InvariantCu
lture, configString, old).Trim(); | |
456 | |
457 foreach(MSBuild.BuildPropertyGroup config in this.projec
t.BuildProject.PropertyGroups) | |
458 { | |
459 // Only care about conditional property groups | |
460 if(config.Condition == null || config.Condition.
Length == 0) | |
461 continue; | |
462 | |
463 // Skip if it isn't the group we want | |
464 if(String.Compare(config.Condition.Trim(), condi
tion, StringComparison.OrdinalIgnoreCase) != 0) | |
465 continue; | |
466 | |
467 // Change the name | |
468 config.Condition = String.Format(CultureInfo.Inv
ariantCulture, configString, newname); | |
469 // Update the name in our config list | |
470 if(configurationsList.ContainsKey(old)) | |
471 { | |
472 ProjectConfig configuration = configurat
ionsList[old]; | |
473 configurationsList.Remove(old); | |
474 configurationsList.Add(newname, configur
ation); | |
475 // notify the configuration of its new n
ame | |
476 configuration.ConfigName = newname; | |
477 } | |
478 | |
479 NotifyOnCfgNameRenamed(old, newname); | |
480 } | |
481 | |
482 return VSConstants.S_OK; | |
483 } | |
484 | |
485 /// <summary> | |
486 /// Cancels a registration for configuration event notification.
| |
487 /// </summary> | |
488 /// <param name="cookie">The cookie used for registration.</para
m> | |
489 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
490 public virtual int UnadviseCfgProviderEvents(uint cookie) | |
491 { | |
492 this.cfgEventSinks.RemoveAt(cookie); | |
493 return VSConstants.S_OK; | |
494 } | |
495 | |
496 /// <summary> | |
497 /// Registers the caller for configuration event notification. | |
498 /// </summary> | |
499 /// <param name="sink">Reference to the IVsCfgProviderEvents int
erface to be called to provide notification of configuration events.</param> | |
500 /// <param name="cookie">Reference to a token representing the c
ompleted registration</param> | |
501 /// <returns>If the method succeeds, it returns S_OK. If it fail
s, it returns an error code.</returns> | |
502 public virtual int AdviseCfgProviderEvents(IVsCfgProviderEvents
sink, out uint cookie) | |
503 { | |
504 cookie = this.cfgEventSinks.Add(sink); | |
505 return VSConstants.S_OK; | |
506 } | |
507 #endregion | |
508 | |
509 #region IVsExtensibleObject Members | |
510 | |
511 /// <summary> | |
512 /// Proved access to an IDispatchable object being a list of con
figuration properties | |
513 /// </summary> | |
514 /// <param name="configurationName">Combined Name and Platform f
or the configuration requested</param> | |
515 /// <param name="configurationProperties">The IDispatchcable obj
ect</param> | |
516 /// <returns>S_OK if successful</returns> | |
517 public virtual int GetAutomationObject(string configurationName,
out object configurationProperties) | |
518 { | |
519 //Init out param | |
520 configurationProperties = null; | |
521 | |
522 string name, platform; | |
523 if(!ProjectConfig.TrySplitConfigurationCanonicalName(con
figurationName, out name, out platform)) | |
524 { | |
525 return VSConstants.E_INVALIDARG; | |
526 } | |
527 | |
528 // Get the configuration | |
529 IVsCfg cfg; | |
530 ErrorHandler.ThrowOnFailure(this.GetCfgOfName(name, plat
form, out cfg)); | |
531 | |
532 // Get the properties of the configuration | |
533 configurationProperties = ((ProjectConfig)cfg).Configura
tionProperties; | |
534 | |
535 return VSConstants.S_OK; | |
536 | |
537 } | |
538 #endregion | |
539 | |
540 #region helper methods | |
541 /// <summary> | |
542 /// Called when a new configuration name was added. | |
543 /// </summary> | |
544 /// <param name="name">The name of configuration just added.</pa
ram> | |
545 private void NotifyOnCfgNameAdded(string name) | |
546 { | |
547 foreach(IVsCfgProviderEvents sink in this.cfgEventSinks) | |
548 { | |
549 ErrorHandler.ThrowOnFailure(sink.OnCfgNameAdded(
name)); | |
550 } | |
551 } | |
552 | |
553 /// <summary> | |
554 /// Called when a config name was deleted. | |
555 /// </summary> | |
556 /// <param name="name">The name of the configuration.</param> | |
557 private void NotifyOnCfgNameDeleted(string name) | |
558 { | |
559 foreach(IVsCfgProviderEvents sink in this.cfgEventSinks) | |
560 { | |
561 ErrorHandler.ThrowOnFailure(sink.OnCfgNameDelete
d(name)); | |
562 } | |
563 } | |
564 | |
565 /// <summary> | |
566 /// Called when a config name was renamed | |
567 /// </summary> | |
568 /// <param name="oldName">Old configuration name</param> | |
569 /// <param name="newName">New configuration name</param> | |
570 private void NotifyOnCfgNameRenamed(string oldName, string newNa
me) | |
571 { | |
572 foreach(IVsCfgProviderEvents sink in this.cfgEventSinks) | |
573 { | |
574 ErrorHandler.ThrowOnFailure(sink.OnCfgNameRename
d(oldName, newName)); | |
575 } | |
576 } | |
577 | |
578 /// <summary> | |
579 /// Called when a platform name was added | |
580 /// </summary> | |
581 /// <param name="platformName">The name of the platform.</param> | |
582 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledP
rivateCode")] | |
583 private void NotifyOnPlatformNameAdded(string platformName) | |
584 { | |
585 foreach(IVsCfgProviderEvents sink in this.cfgEventSinks) | |
586 { | |
587 ErrorHandler.ThrowOnFailure(sink.OnPlatformNameA
dded(platformName)); | |
588 } | |
589 } | |
590 | |
591 /// <summary> | |
592 /// Called when a platform name was deleted | |
593 /// </summary> | |
594 /// <param name="platformName">The name of the platform.</param> | |
595 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledP
rivateCode")] | |
596 private void NotifyOnPlatformNameDeleted(string platformName) | |
597 { | |
598 foreach(IVsCfgProviderEvents sink in this.cfgEventSinks) | |
599 { | |
600 ErrorHandler.ThrowOnFailure(sink.OnPlatformNameD
eleted(platformName)); | |
601 } | |
602 } | |
603 | |
604 /// <summary> | |
605 /// Gets all the platforms defined in the project | |
606 /// </summary> | |
607 /// <returns>An array of platform names.</returns> | |
608 private string[] GetPlatformsFromProject() | |
609 { | |
610 string[] platforms = this.ProjectMgr.BuildProject.GetCon
ditionedPropertyValues(ProjectFileConstants.Platform); | |
611 | |
612 if(platforms == null || platforms.Length == 0) | |
613 { | |
614 return new string[] { AnyCPUPlatform }; | |
615 } | |
616 | |
617 for(int i = 0; i < platforms.Length; i++) | |
618 { | |
619 platforms[i] = ConvertPlatformToVsProject(platfo
rms[i]); | |
620 } | |
621 | |
622 return platforms; | |
623 } | |
624 | |
625 /// <summary> | |
626 /// Return the supported platform names. | |
627 /// </summary> | |
628 /// <returns>An array of supported platform names.</returns> | |
629 private string[] GetSupportedPlatformsFromProject() | |
630 { | |
631 string platforms = this.ProjectMgr.BuildProject.GetEvalu
atedProperty(ProjectFileConstants.AvailablePlatforms); | |
632 | |
633 if(platforms == null) | |
634 { | |
635 return new string[] { }; | |
636 } | |
637 | |
638 if(platforms.Contains(",")) | |
639 { | |
640 return platforms.Split(','); | |
641 } | |
642 | |
643 return new string[] { platforms }; | |
644 } | |
645 | |
646 /// <summary> | |
647 /// Helper function to convert AnyCPU to Any CPU. | |
648 /// </summary> | |
649 /// <param name="oldName">The oldname.</param> | |
650 /// <returns>The new name.</returns> | |
651 private static string ConvertPlatformToVsProject(string oldPlatf
ormName) | |
652 { | |
653 if(String.Compare(oldPlatformName, ProjectFileValues.Any
CPU, StringComparison.OrdinalIgnoreCase) == 0) | |
654 { | |
655 return AnyCPUPlatform; | |
656 } | |
657 | |
658 return oldPlatformName; | |
659 } | |
660 | |
661 /// <summary> | |
662 /// Common method for handling platform names. | |
663 /// </summary> | |
664 /// <param name="celt">Specifies the requested number of platfor
m names. If this number is unknown, celt can be zero.</param> | |
665 /// <param name="names">On input, an allocated array to hold the
number of platform names specified by celt. This parameter can also be null if
the celt parameter is zero. On output, names contains platform names</param> | |
666 /// <param name="actual">A count of the actual number of platfor
m names returned.</param> | |
667 /// <param name="platforms">An array of available platform names
</param> | |
668 /// <returns>A count of the actual number of platform names retu
rned.</returns> | |
669 /// <devremark>The platforms array is never null. It is assured
by the callers.</devremark> | |
670 private static int GetPlatforms(uint celt, string[] names, uint[
] actual, string[] platforms) | |
671 { | |
672 Debug.Assert(platforms != null, "The plaforms array shou
ld never be null"); | |
673 if(names == null) | |
674 { | |
675 if(actual == null || actual.Length == 0) | |
676 { | |
677 throw new ArgumentException(SR.GetString
(SR.InvalidParameter, CultureInfo.CurrentUICulture), "actual"); | |
678 } | |
679 | |
680 actual[0] = (uint)platforms.Length; | |
681 return VSConstants.S_OK; | |
682 } | |
683 | |
684 //Degenarate case | |
685 if(celt == 0) | |
686 { | |
687 if(actual != null && actual.Length != 0) | |
688 { | |
689 actual[0] = (uint)platforms.Length; | |
690 } | |
691 | |
692 return VSConstants.S_OK; | |
693 } | |
694 | |
695 uint returned = 0; | |
696 for(int i = 0; i < platforms.Length && names.Length > re
turned; i++) | |
697 { | |
698 names[returned] = platforms[i]; | |
699 returned++; | |
700 } | |
701 | |
702 if(actual != null && actual.Length != 0) | |
703 { | |
704 actual[0] = returned; | |
705 } | |
706 | |
707 if(celt > returned) | |
708 { | |
709 return VSConstants.S_FALSE; | |
710 } | |
711 | |
712 return VSConstants.S_OK; | |
713 } | |
714 #endregion | |
715 } | |
716 } | |
OLD | NEW |