dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.27k stars 4.73k forks source link

Create COM objects on PowerShell gives an error `Constructor on type 'System.__ComObject' not found.` #57107

Closed adityapatwardhan closed 3 years ago

adityapatwardhan commented 3 years ago

Description

On a PowerShell build with .NET 6 Preview 7, when a new instance of a COM object is done, we get an error: Constructor on type 'System.__ComObject' not found. which is System.MissingMethodException

Gist for sample code to repro the error:

https://gist.github.com/adityapatwardhan/954af5c2d894d889e1465c614ecf7e1a

Configuration

.NET 6 Preview 7 SDK on Windows 10 x64.

Regression?

Yes, from .NET 6 Preview 6

Other information

Repro for the issue is on PowerShell built against .NET 6 Preview 7 SDK.

PS C:> $fileSystem = New-Object -ComObject scripting.filesystemobject New-Object: Constructor on type 'System.__ComObject' not found. PS C:> Get-Error

Exception : Type : System.MissingMethodException Message : Constructor on type 'System.__ComObject' not found. TargetSite : Name : CreateInstanceImpl DeclaringType : System.RuntimeType, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e MemberType : Method Module : System.Private.CoreLib.dll Source : System.Private.CoreLib HResult : -2146233069 StackTrace : at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) in System.Private.CoreLib.dll:token 0x60006c6+0x173 at System.Activator.CreateInstance(Type type, Object[] args) in System.Private.CoreLib.dll:token 0x60009e0+0x0 at Microsoft.PowerShell.Commands.NewObjectCommand.SafeCreateInstance(Type t, Object[] args) in D:\PSGit\PowerShell\src\Microsoft.PowerShell.Commands.Utility\commands\utility\New-Object.cs:line 359 CategoryInfo : InvalidOperation: (:) [New-Object], MissingMethodException FullyQualifiedErrorId : NoPublicCtorMatch,Microsoft.PowerShell.Commands.NewObjectCommand InvocationInfo : MyCommand : New-Object ScriptLineNumber : 1 OffsetInLine : 15 HistoryId : 9 Line : $fileSystem = New-Object -ComObject scripting.filesystemobject PositionMessage : At line:1 char:15

dotnet-issue-labeler[bot] commented 3 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

mmitche commented 3 years ago

@danmoseley Can you help out @adityapatwardhan with a workaround?

agocke commented 3 years ago

@elinor-fung Could you take a look and see if we regressed something here in COM?

elinor-fung commented 3 years ago

Regression from https://github.com/dotnet/runtime/pull/54471.

RuntimeType.CreateInstanceImpl no longer going down this branch for COM: https://github.com/dotnet/runtime/blob/dbb2b53e0caeeb32888f83a5c6fe6db8525398de/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs#L3654-L3658

Because this is returning false: https://github.com/dotnet/runtime/blob/dbb2b53e0caeeb32888f83a5c6fe6db8525398de/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs#L463-L467

cc @AaronRobinsonMSFT

elinor-fung commented 3 years ago

@adityapatwardhan a workaround here would be to use the Activator.CreateInstance that just takes a Type instead of explicitly passing an empty array for the args. So in your gist:

- object res = System.Activator.CreateInstance(t, Array.Empty<object>());
+ object res = System.Activator.CreateInstance(t);
AaronRobinsonMSFT commented 3 years ago

Doh! No one was more surprised than I when I made those changes and all our tests passed. It would appear we have a test hole. @elinor-fung Thanks for root causing this. Please let me know if you need any help on the fix.

adityapatwardhan commented 3 years ago

@daxian-dbw as FYI