Skip to content

COM objects are not enumerating properly #3775

Closed

Description

Repro

Open a File Explorer window first if you find $w.Count is 0

PSv6> $s = New-Object -ComObject "Shell.Application"
PSv6> $w = $s.Windows()
PSv6> $w.Count
1
PSv6> $w  ## dump $w, and powershell should enumerate $w to unwrap the collection

Expected Behavior

$w is unwrapped and the contained items are dumpped out (PSv5 behavior)

Application          : System.__ComObject
Parent               : System.__ComObject
Container            :
Document             : System.__ComObject
TopLevelContainer    : True
Type                 :
Left                 : -32000
Top                  : -32000
Width                : 160
Height               : 28
LocationName         : 6.0.0-beta1
LocationURL          : file:///D:/PowerShell/6.0.0-beta1
Busy                 : False
Name                 : File Explorer
HWND                 : 923136
FullName             : C:\WINDOWS\Explorer.EXE
Path                 : C:\WINDOWS\
Visible              : True
StatusBar            : False
StatusText           :
ToolBar              : 1
MenuBar              : False
FullScreen           : False
ReadyState           : 4
Offline              : False
Silent               : False
RegisterAsBrowser    : False
RegisterAsDropTarget : True
TheaterMode          : False
AddressBar           : True
Resizable            : True

Actual Behavior

Count
-----
    2

Environment

PSv6> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.0.0-beta
PSEdition                      Core
BuildVersion                   3.0.0.0
CLRVersion
GitCommitId                    v6.0.0-beta.1
OS                             Microsoft Windows 10.0.15063
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Additional Observation

The problem appears to be this:

PSv6>  $w._NewEnum()
An error occurred while enumerating through a collection: Could not load type 'System.Runtime.InteropServices.ComTypes.IEnumerator' from assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=7cec85d7bea7798e'..
At line:1 char:2
+  $w._NewEnum()
+  ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.__ComObject:__ComObject) [], RuntimeException
    + FullyQualifiedErrorId : BadEnumeration

Activity

  1. added
    WG-Enginecore PowerShell engine, interpreter, and runtime
    Breaking-Changebreaking change that may affect users
    Issue-BugIssue has been identified as a bug in the product
    on May 12, 2017
  2. daxian-dbw commented on May 12, 2017

    @daxian-dbw
    Member

    Good catch 👍
    My investigation shows this is a bug in .NET Core 2.0. A dotnet/corefx issue has been filed: https://github.com/dotnet/corefx/issues/19731

    What happens is that powershell successfully casts the ShellWindows object to IEnumerable, and then a TypeLoadException is thrown when calling GetEnumerator() on the IEnumerable object. PowerShell catches the exception and treat the object as non-enumerable.

  3. daxian-dbw commented on May 12, 2017

    @daxian-dbw
    Member

    The issue description was updated to make it easy to understand the problem.

  4. modified the milestones: , , on May 13, 2017
  5. daxian-dbw commented on May 24, 2017

    @daxian-dbw
    Member

    Reply from CoreCLR team on dotnet/corefx#19731

    Thanks for reporting this issue. As previously discussed, CoreCLR doesn't support IDispatch (and that's why you are implementing your own IDispatch). IEnumerable.GetEnumerator uses IDispatch.Invoke(DISPID_NEWENUM) under the hood (that's the convention for IDispatch objects to support enumeration). You need to write your own enumeration code to support that pattern in CoreCLR. Based on what you already have (IDispatch and VARIANT support), it should be pretty straight-forward. I'll be happy to help out offline if you need any help.

    So we need to write the enumeration code ourselves.

  6. iSazonov commented on May 25, 2017

    @iSazonov
    Collaborator

    Should we remove Waiting - NetStandard20 label?

  7. added
    Blockedblocked on something external to this repo
    and removed on May 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Blockedblocked on something external to this repoBreaking-Changebreaking change that may affect usersIssue-BugIssue has been identified as a bug in the productWG-Enginecore PowerShell engine, interpreter, and runtime

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions