mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Update 'Utils.IsComObject' to use 'Marshal.IsComObject' since CAS is no longer supported in .NET Core (#7344)
A comment from the existing `Utils.IsComObject` mentions that: "We can't use System.Runtime.InteropServices.Marshal.IsComObject(obj) since it doesn't work in partial trust." Partial trust is a concept of Code Access Security (CAS)/Security-Transparent. CAS and Security-Transparent are no longer supported in .NET Core, so we should use `Marshal.IsComObject` instead.
This commit is contained in:
@@ -1345,43 +1345,26 @@ namespace System.Management.Automation
|
||||
internal static readonly char[] PathSearchTrimEnd = { (char)0x9, (char)0xA, (char)0xB, (char)0xC, (char)0xD, (char)0x20, (char)0x85, (char)0xA0 };
|
||||
}
|
||||
|
||||
#if !UNIX
|
||||
// This is to reduce the runtime overhead of the feature query
|
||||
private static readonly Type ComObjectType = typeof(object).Assembly.GetType("System.__ComObject");
|
||||
#endif
|
||||
|
||||
internal static bool IsComObject(PSObject psObject)
|
||||
{
|
||||
#if UNIX
|
||||
return false;
|
||||
#else
|
||||
if (psObject == null) { return false; }
|
||||
|
||||
object obj = PSObject.Base(psObject);
|
||||
return IsComObject(obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A COM object could be directly of the type 'System.__ComObject', or it could be a strongly typed RWC,
|
||||
/// whose specific type derives from 'System.__ComObject'.
|
||||
/// A strongly typed RWC can be created via the 'new' operation with a Primary Interop Assembly (PIA).
|
||||
/// For example, with the PIA 'Microsoft.Office.Interop.Excel', you can write the following code:
|
||||
/// var excelApp = new Microsoft.Office.Interop.Excel.Application();
|
||||
/// Type type = excelApp.GetType();
|
||||
/// Type comObjectType = typeof(object).Assembly.GetType("System.__ComObject");
|
||||
/// Console.WriteLine("excelApp type: {0}", type.FullName);
|
||||
/// Console.WriteLine("Is __ComObject assignable from? {0}", comObjectType.IsAssignableFrom(type));
|
||||
/// and the results are:
|
||||
/// excelApp type: Microsoft.Office.Interop.Excel.ApplicationClass
|
||||
/// Is __ComObject assignable from? True
|
||||
/// </summary>
|
||||
internal static bool IsComObject(object obj)
|
||||
{
|
||||
#if UNIX
|
||||
return false;
|
||||
#else
|
||||
// We can't use System.Runtime.InteropServices.Marshal.IsComObject(obj) since it doesn't work in partial trust.
|
||||
//
|
||||
// There could be strongly typed RWCs whose type is not 'System.__ComObject', but the more specific type should
|
||||
// derive from 'System.__ComObject'. The strongly typed RWCs can be created with 'new' operation via the Primay
|
||||
// Interop Assembly (PIA).
|
||||
// For example, with the PIA 'Microsoft.Office.Interop.Excel', you can write the following code:
|
||||
// var excelApp = new Microsoft.Office.Interop.Excel.Application();
|
||||
// Type type = excelApp.GetType();
|
||||
// Type comObjectType = typeof(object).Assembly.GetType("System.__ComObject");
|
||||
// Console.WriteLine("excelApp type: {0}", type.FullName);
|
||||
// Console.WriteLine("Is __ComObject assignable from? {0}", comObjectType.IsAssignableFrom(type));
|
||||
// and the results are:
|
||||
// excelApp type: Microsoft.Office.Interop.Excel.ApplicationClass
|
||||
// Is __ComObject assignable from? True
|
||||
return obj != null && ComObjectType.IsAssignableFrom(obj.GetType());
|
||||
return obj != null && Marshal.IsComObject(obj);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,7 +499,7 @@ namespace System.Management.Automation.Language
|
||||
typeof(VariableOps).GetMethod(nameof(VariableOps.SetVariableValue), staticFlags);
|
||||
|
||||
internal static readonly MethodInfo Utils_IsComObject =
|
||||
typeof(Utils).GetMethod(nameof(Utils.IsComObject), staticFlags, binder: null, types: new Type[] {typeof(object)}, modifiers: null);
|
||||
typeof(Utils).GetMethod(nameof(Utils.IsComObject), staticFlags);
|
||||
|
||||
internal static readonly MethodInfo ClassOps_ValidateSetProperty =
|
||||
typeof(ClassOps).GetMethod(nameof(ClassOps.ValidateSetProperty), staticPublicFlags);
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
@@ -619,7 +620,7 @@ namespace System.Management.Automation.Language
|
||||
GetRestrictions(target))).WriteToDebugLog(this);
|
||||
}
|
||||
|
||||
if (Utils.IsComObject(targetValue))
|
||||
if (Marshal.IsComObject(targetValue))
|
||||
{
|
||||
// Pretend that all com objects are enumerable, even if they aren't. We do this because it's technically impossible
|
||||
// to know if a com object is enumerable without just trying to cast it to IEnumerable. We could generate a rule like:
|
||||
@@ -715,7 +716,12 @@ namespace System.Management.Automation.Language
|
||||
|
||||
private static IEnumerator NotEnumerableRule(CallSite site, object obj)
|
||||
{
|
||||
if (!(obj is PSObject) && !(obj is IEnumerable) && !(obj is IEnumerator) && !(obj is DataTable) && !Utils.IsComObject(obj))
|
||||
if (obj == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(obj is PSObject) && !(obj is IEnumerable) && !(obj is IEnumerator) && !(obj is DataTable) && !Marshal.IsComObject(obj))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -4988,7 +4994,7 @@ namespace System.Management.Automation.Language
|
||||
if (target.Value is PSObject && (PSObject.Base(target.Value) != target.Value))
|
||||
{
|
||||
Object baseObject = PSObject.Base(target.Value);
|
||||
if (baseObject != null && Utils.IsComObject(baseObject))
|
||||
if (baseObject != null && Marshal.IsComObject(baseObject))
|
||||
{
|
||||
// We unwrap only if the 'base' is a COM object. It's unnecessary to unwrap in other cases,
|
||||
// especially in the case of strings, we would lose instance members on the PSObject.
|
||||
@@ -5859,7 +5865,7 @@ namespace System.Management.Automation.Language
|
||||
(value.Value is PSObject && (PSObject.Base(value.Value) != value.Value)))
|
||||
{
|
||||
Object baseObject = PSObject.Base(target.Value);
|
||||
if (baseObject != null && Utils.IsComObject(baseObject))
|
||||
if (baseObject != null && Marshal.IsComObject(baseObject))
|
||||
{
|
||||
// We unwrap only if the 'base' of 'target' is a COM object. It's unnecessary to unwrap in other cases,
|
||||
// especially in the case that 'target' is a string, we would lose instance members on the PSObject.
|
||||
@@ -6380,7 +6386,7 @@ namespace System.Management.Automation.Language
|
||||
args.Any(mo => mo.Value is PSObject && (PSObject.Base(mo.Value) != mo.Value)))
|
||||
{
|
||||
Object baseObject = PSObject.Base(target.Value);
|
||||
if (baseObject != null && Utils.IsComObject(baseObject))
|
||||
if (baseObject != null && Marshal.IsComObject(baseObject))
|
||||
{
|
||||
// We unwrap only if the 'base' of 'target' is a COM object. It's unnecessary to unwrap in other cases,
|
||||
// especially in the case that 'target' is a string, we would lose instance members on the PSObject.
|
||||
|
||||
Reference in New Issue
Block a user