PageRenderTime 59ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/System.Management.Automation/engine/COM/ComAdapter.cs

https://gitlab.com/unofficial-mirrors/PowerShell
C# | 328 lines | 179 code | 32 blank | 117 comment | 18 complexity | 17084d4f5508e58125c7e46664828d2d MD5 | raw file
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License.
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Text;
  6. using System.ComponentModel;
  7. using Microsoft.PowerShell;
  8. namespace System.Management.Automation
  9. {
  10. /// <summary>
  11. /// Implements Adapter for the COM objects.
  12. /// </summary>
  13. internal class ComAdapter : Adapter
  14. {
  15. private readonly ComTypeInfo _comTypeInfo;
  16. /// <summary>
  17. /// Constructor for the ComAdapter
  18. /// </summary>
  19. /// <param name="typeinfo">typeinfo for the com object we are adapting</param>
  20. internal ComAdapter(ComTypeInfo typeinfo)
  21. {
  22. Diagnostics.Assert(typeinfo != null, "Caller to verify typeinfo is not null.");
  23. _comTypeInfo = typeinfo;
  24. }
  25. internal static string GetComTypeName(string clsid)
  26. {
  27. StringBuilder firstType = new StringBuilder("System.__ComObject");
  28. firstType.Append("#{");
  29. firstType.Append(clsid);
  30. firstType.Append("}");
  31. return firstType.ToString();
  32. }
  33. /// <summary>
  34. /// Returns the TypeNameHierarchy out of an object
  35. /// </summary>
  36. /// <param name="obj">object to get the TypeNameHierarchy from</param>
  37. protected override IEnumerable<string> GetTypeNameHierarchy(object obj)
  38. {
  39. yield return GetComTypeName(_comTypeInfo.Clsid);
  40. foreach (string baseType in GetDotNetTypeNameHierarchy(obj))
  41. {
  42. yield return baseType;
  43. }
  44. }
  45. /// <summary>
  46. /// Returns null if memberName is not a member in the adapter or
  47. /// the corresponding PSMemberInfo
  48. /// </summary>
  49. /// <param name="obj">object to retrieve the PSMemberInfo from</param>
  50. /// <param name="memberName">name of the member to be retrieved</param>
  51. /// <returns>The PSMemberInfo corresponding to memberName from obj</returns>
  52. protected override T GetMember<T>(object obj, string memberName)
  53. {
  54. ComProperty prop;
  55. if (_comTypeInfo.Properties.TryGetValue(memberName, out prop))
  56. {
  57. if (prop.IsParameterized)
  58. {
  59. if (typeof(T).IsAssignableFrom(typeof(PSParameterizedProperty)))
  60. {
  61. return new PSParameterizedProperty(prop.Name, this, obj, prop) as T;
  62. }
  63. }
  64. else if (typeof(T).IsAssignableFrom(typeof(PSProperty)))
  65. {
  66. return new PSProperty(prop.Name, this, obj, prop) as T;
  67. }
  68. }
  69. ComMethod method;
  70. if (typeof(T).IsAssignableFrom(typeof(PSMethod)) &&
  71. (_comTypeInfo != null) && (_comTypeInfo.Methods.TryGetValue(memberName, out method)))
  72. {
  73. PSMethod mshMethod = new PSMethod(method.Name, this, obj, method);
  74. return mshMethod as T;
  75. }
  76. return null;
  77. }
  78. /// <summary>
  79. /// Retrieves all the members available in the object.
  80. /// The adapter implementation is encouraged to cache all properties/methods available
  81. /// in the first call to GetMember and GetMembers so that subsequent
  82. /// calls can use the cache.
  83. /// In the case of the .NET adapter that would be a cache from the .NET type to
  84. /// the public properties and fields available in that type.
  85. /// In the case of the DirectoryEntry adapter, this could be a cache of the objectClass
  86. /// to the properties available in it.
  87. /// </summary>
  88. /// <param name="obj">object to get all the member information from</param>
  89. /// <returns>all members in obj</returns>
  90. protected override PSMemberInfoInternalCollection<T> GetMembers<T>(object obj)
  91. {
  92. PSMemberInfoInternalCollection<T> collection = new PSMemberInfoInternalCollection<T>();
  93. bool lookingForProperties = typeof(T).IsAssignableFrom(typeof(PSProperty));
  94. bool lookingForParameterizedProperties = typeof(T).IsAssignableFrom(typeof(PSParameterizedProperty));
  95. if (lookingForProperties || lookingForParameterizedProperties)
  96. {
  97. foreach (ComProperty prop in _comTypeInfo.Properties.Values)
  98. {
  99. if (prop.IsParameterized)
  100. {
  101. if (lookingForParameterizedProperties)
  102. {
  103. collection.Add(new PSParameterizedProperty(prop.Name, this, obj, prop) as T);
  104. }
  105. }
  106. else if (lookingForProperties)
  107. {
  108. collection.Add(new PSProperty(prop.Name, this, obj, prop) as T);
  109. }
  110. }
  111. }
  112. bool lookingForMethods = typeof(T).IsAssignableFrom(typeof(PSMethod));
  113. if (lookingForMethods)
  114. {
  115. foreach (ComMethod method in _comTypeInfo.Methods.Values)
  116. {
  117. if (collection[method.Name] == null)
  118. {
  119. PSMethod mshmethod = new PSMethod(method.Name, this, obj, method);
  120. collection.Add(mshmethod as T);
  121. }
  122. }
  123. }
  124. return collection;
  125. }
  126. /// <summary>
  127. /// Returns an array with the property attributes
  128. /// </summary>
  129. /// <param name="property">property we want the attributes from</param>
  130. /// <returns>an array with the property attributes</returns>
  131. protected override AttributeCollection PropertyAttributes(PSProperty property)
  132. {
  133. return new AttributeCollection();
  134. }
  135. /// <summary>
  136. /// Returns the value from a property coming from a previous call to DoGetProperty
  137. /// </summary>
  138. /// <param name="property">PSProperty coming from a previous call to DoGetProperty</param>
  139. /// <returns>The value of the property</returns>
  140. protected override object PropertyGet(PSProperty property)
  141. {
  142. ComProperty prop = (ComProperty)property.adapterData;
  143. return prop.GetValue(property.baseObject);
  144. }
  145. /// <summary>
  146. /// Sets the value of a property coming from a previous call to DoGetProperty
  147. /// </summary>
  148. /// <param name="property">PSProperty coming from a previous call to DoGetProperty</param>
  149. /// <param name="setValue">value to set the property with</param>
  150. /// <param name="convertIfPossible">instructs the adapter to convert before setting, if the adapter supports conversion</param>
  151. protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible)
  152. {
  153. ComProperty prop = (ComProperty)property.adapterData;
  154. prop.SetValue(property.baseObject, setValue);
  155. }
  156. /// <summary>
  157. /// Returns true if the property is settable
  158. /// </summary>
  159. /// <param name="property">property to check</param>
  160. /// <returns>true if the property is settable</returns>
  161. protected override bool PropertyIsSettable(PSProperty property)
  162. {
  163. ComProperty prop = (ComProperty)property.adapterData;
  164. return prop.IsSettable;
  165. }
  166. /// <summary>
  167. /// Returns true if the property is gettable
  168. /// </summary>
  169. /// <param name="property">property to check</param>
  170. /// <returns>true if the property is gettable</returns>
  171. protected override bool PropertyIsGettable(PSProperty property)
  172. {
  173. ComProperty prop = (ComProperty)property.adapterData;
  174. return prop.IsGettable;
  175. }
  176. /// <summary>
  177. /// Returns the name of the type corresponding to the property
  178. /// </summary>
  179. /// <param name="property">PSProperty obtained in a previous DoGetProperty</param>
  180. /// <param name="forDisplay">True if the result is for display purposes only</param>
  181. /// <returns>the name of the type corresponding to the property</returns>
  182. protected override string PropertyType(PSProperty property, bool forDisplay)
  183. {
  184. ComProperty prop = (ComProperty)property.adapterData;
  185. return forDisplay ? ToStringCodeMethods.Type(prop.Type) : prop.Type.FullName;
  186. }
  187. /// <summary>
  188. /// get the property signature.
  189. /// </summary>
  190. /// <param name="property">property object whose signature we want</param>
  191. /// <returns>string representing the signature of the property</returns>
  192. protected override string PropertyToString(PSProperty property)
  193. {
  194. ComProperty prop = (ComProperty)property.adapterData;
  195. return prop.ToString();
  196. }
  197. #region Methods
  198. /// <summary>
  199. /// Called after a non null return from GetMethodData to try to call
  200. /// the method with the arguments
  201. /// </summary>
  202. /// <param name="method">the non empty return from GetMethods</param>
  203. /// <param name="arguments">the arguments to use</param>
  204. /// <returns>the return value for the method</returns>
  205. protected override object MethodInvoke(PSMethod method, object[] arguments)
  206. {
  207. ComMethod commethod = (ComMethod)method.adapterData;
  208. return commethod.InvokeMethod(method, arguments);
  209. }
  210. /// <summary>
  211. /// Called after a non null return from GetMethodData to return the overloads
  212. /// </summary>
  213. /// <param name="method">the return of GetMethodData</param>
  214. /// <returns></returns>
  215. protected override Collection<String> MethodDefinitions(PSMethod method)
  216. {
  217. ComMethod commethod = (ComMethod)method.adapterData;
  218. return commethod.MethodDefinitions();
  219. }
  220. #endregion
  221. #region parameterized property
  222. /// <summary>
  223. /// Returns the name of the type corresponding to the property's value
  224. /// </summary>
  225. /// <param name="property">property obtained in a previous GetMember</param>
  226. /// <returns>the name of the type corresponding to the member</returns>
  227. protected override string ParameterizedPropertyType(PSParameterizedProperty property)
  228. {
  229. ComProperty prop = (ComProperty)property.adapterData;
  230. return prop.Type.FullName;
  231. }
  232. /// <summary>
  233. /// Returns true if the property is settable
  234. /// </summary>
  235. /// <param name="property">property to check</param>
  236. /// <returns>true if the property is settable</returns>
  237. protected override bool ParameterizedPropertyIsSettable(PSParameterizedProperty property)
  238. {
  239. ComProperty prop = (ComProperty)property.adapterData;
  240. return prop.IsSettable;
  241. }
  242. /// <summary>
  243. /// Returns true if the property is gettable
  244. /// </summary>
  245. /// <param name="property">property to check</param>
  246. /// <returns>true if the property is gettable</returns>
  247. protected override bool ParameterizedPropertyIsGettable(PSParameterizedProperty property)
  248. {
  249. ComProperty prop = (ComProperty)property.adapterData;
  250. return prop.IsGettable;
  251. }
  252. /// <summary>
  253. /// Called after a non null return from GetMember to get the property value
  254. /// </summary>
  255. /// <param name="property">the non empty return from GetMember</param>
  256. /// <param name="arguments">the arguments to use</param>
  257. /// <returns>the return value for the property</returns>
  258. protected override object ParameterizedPropertyGet(PSParameterizedProperty property, object[] arguments)
  259. {
  260. ComProperty prop = (ComProperty)property.adapterData;
  261. return prop.GetValue(property.baseObject, arguments);
  262. }
  263. /// <summary>
  264. /// Called after a non null return from GetMember to set the property value
  265. /// </summary>
  266. /// <param name="property">the non empty return from GetMember</param>
  267. /// <param name="setValue">the value to set property with</param>
  268. /// <param name="arguments">the arguments to use</param>
  269. protected override void ParameterizedPropertySet(PSParameterizedProperty property, object setValue, object[] arguments)
  270. {
  271. ComProperty prop = (ComProperty)property.adapterData;
  272. prop.SetValue(property.baseObject, setValue, arguments);
  273. }
  274. /// <summary>
  275. /// Returns the string representation of the property in the object
  276. /// </summary>
  277. /// <param name="property">property obtained in a previous GetMember</param>
  278. /// <returns>the string representation of the property in the object</returns>
  279. protected override string ParameterizedPropertyToString(PSParameterizedProperty property)
  280. {
  281. ComProperty prop = (ComProperty)property.adapterData;
  282. return prop.ToString();
  283. }
  284. /// <summary>
  285. /// Called after a non null return from GetMember to return the overloads
  286. /// </summary>
  287. /// <param name="property">the return of GetMember</param>
  288. protected override Collection<String> ParameterizedPropertyDefinitions(PSParameterizedProperty property)
  289. {
  290. ComProperty prop = (ComProperty)property.adapterData;
  291. Collection<string> returnValue = new Collection<string> { prop.GetDefinition() };
  292. return returnValue;
  293. }
  294. #endregion parameterized property
  295. }
  296. }