FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Make PowerShell Core enumerate COM collections by daxian-dbw · Pull Request #4553 · PowerShell/PowerShell · GitHub

Make PowerShell Core enumerate COM collections - #4553

Merged
Ilya (iSazonov) merged 11 commits into
PowerShell:masterfrom
daxian-dbw:COM
Aug 17, 2017
Merged

Make PowerShell Core enumerate COM collections#4553
Ilya (iSazonov) merged 11 commits into
PowerShell:masterfrom
daxian-dbw:COM

Conversation

Copy link
Copy Markdown
Member

Fix #3775

'GetEnumerator()' is not supported on COM collections in .NET Core (see https://github.com/dotnet/corefx/issues/19731), so we need to have our own implementation to enumerate COM collections.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

LGTM with minor comment


return enumVariant != null ? new ComEnumerator(enumVariant) : null;
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Add extra line at the end.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Added a new line.

Copy link
Copy Markdown
Member Author

I should use Measure-Object in the test but instead used Measure-Command, which pops for mandatory parameter input and thus caused the build to hang. It's fixed now.


internal static ComEnumerator Create(object comObject)
{
if (!comObject.GetType().IsCOMObject) { return null; }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Should we check comObject != null ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Will add a null check here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Closed.

}
}

return enumVariant != null ? new ComEnumerator(enumVariant) : null;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Maybe use else to exclude duplicate check with line 399?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

It's not a duplicate check, line 416 could make enumVariant not null or continue to be null.

Ilya (iSazonov) Aug 15, 2017
edited
Loading

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I meant that here slightly hidden logic. Maybe:

// if IEnumVARIANT interface
var enumVariant = comObject as COM.IEnumVARIANT;
if (enumVariant != null)
{
    return new ComEnumerator(enumVariant);
}

//  if  a collection
var enumerable = comObject as IEnumerable; 
...
    enumVariant = result as COM.IEnumVARIANT; 
    if (enumVariant != null)
    {
        return new ComEnumerator(enumVariant);
    }
...

return null;  // any warnings for users?

Dongbo Wang (daxian-dbw) Aug 15, 2017
edited
Loading

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This is more of a coding style rather than an issue that needs to be corrected.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Wait, I see your point now -- there will be one more null check if the COM object is already an enum variant. Will update the code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Code updated.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Thanks for understanding and sorry that I was unclear.

Describe 'Basic COM Tests' -Tags "CI" {
It "Should enumerate ShellWindows" {
$shell = New-Object -ComObject "Shell.Application"
$windows = $shell.Windows()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Is it work on Core and IoT?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Good catch. NanoServer and IoT don't have the shell, so these tests don't apply. Will update.

Copy link
Copy Markdown
Member Author

Ilya (@iSazonov) I have addressed your comments. Please take another look. Thanks!

Ilya (iSazonov) dismissed stale reviews from Jason Shirk (lzybkr) and Aditya Patwardhan (adityapatwardhan) August 15, 2017 05:34

We have new commits - please take another look.

Copy link
Copy Markdown
Collaborator

Jason Shirk (@lzybkr) Aditya Patwardhan (@adityapatwardhan) We have new commits - please take another look.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

LGTM

}
}

return enumVariant != null ? new ComEnumerator(enumVariant) : null;

Ilya (iSazonov) Aug 15, 2017
edited
Loading

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I meant that here slightly hidden logic. Maybe:

// if IEnumVARIANT interface
var enumVariant = comObject as COM.IEnumVARIANT;
if (enumVariant != null)
{
    return new ComEnumerator(enumVariant);
}

//  if  a collection
var enumerable = comObject as IEnumerable; 
...
    enumVariant = result as COM.IEnumVARIANT; 
    if (enumVariant != null)
    {
        return new ComEnumerator(enumVariant);
    }
...

return null;  // any warnings for users?

}
catch (Exception)
{
/* Catch all exception. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Obvious comment and typo (exception -> exceptions). Catch all exceptions - why? Please enhance the comment or remove.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Fixed.

Copy link
Copy Markdown
Collaborator

Jason Shirk (@lzybkr) Can you approve?

Dongbo Wang (daxian-dbw) commented Aug 16, 2017
edited
Loading

Copy link
Copy Markdown
Member Author

Ilya (@iSazonov) Jason probably doesn't have time to come back and approve it again, so it's up to the maintainer's judgment to see if it's necessary for reviewers who had approved to approve again. There are some guidelines you can use, for example:

  1. are the changes after the previous approval fundamental or just touch-ups
  2. are the changes to address comments left by the reviewer who previously approved

Certainly, you will get your own guidelines as you become more experienced in this role.

Copy link
Copy Markdown
Collaborator

Dongbo Wang (@daxian-dbw) Thank you for the helpful comment!

In this case, it's more of a courtesy - I have to show respect and ask him after I formally dismissed his approval.

Copy link
Copy Markdown
Member Author

Ilya (@iSazonov) Another related comment. I usually don't dismiss a reviewer's approval unless the PR needs some fundamental changes (e.g. design flaw, logic changes and etc.). If the following-up changes are touch-ups or minor fixes (like typo, a null condition check, test fix-up), I think it's fine to keep the previous approval, and once the minor issues are addressed, you can approve the PR and merge it.

Copy link
Copy Markdown
Collaborator

Dongbo Wang (@daxian-dbw) I wonder why CI AppVeyor failed?

Copy link
Copy Markdown
Member Author

I have investigated the failure, it actually a bug in Binder, more specifically at here, the restriction generated in the call to this.DeferForPSObject doesn't respect the fact that the baseobject needs to be a COM object.

A repro would be:

$shell = New-Object -ComObject "Shell.Application"
$folder = $shell.Namespace("F:\tmp")
#$item = $folder.Items().Item(0)
$item = $folder.Items() | select -Last 1
$item.Name


$members = new-object System.Collections.ObjectModel.Collection[System.Management.Automation.PSMemberInfo]
$n=new-object Management.Automation.PSNoteProperty a,1
$members.Add($n)
$r=add-member -InputObject a -MemberType MemberSet -Name Name -Value $members -passthru
$r.Name.a

The $r.Name.a is supposed to return 1. If you run the lower part first then upper part, then all work fine.
This happens when a COM object is wrapped into a PSObject, which is the case when the COM object is returned from a pipeline, like the above repro code.

I cannot open an issue until this PR is merged because the repro requires enumerating a COM collection.
I have updated the test to not access Name member, so it would be good now. When I resolve the bug, I will update the COM basic test to keep accessing the Name member.

Ilya (iSazonov) commented Aug 17, 2017
edited
Loading

Copy link
Copy Markdown
Collaborator

Dongbo Wang (@daxian-dbw) Maybe made two commits for code and tests before rebase and merge?

Copy link
Copy Markdown
Member Author

Ilya (@iSazonov) Please just choose 'Squash and merge'. It's a simple fix and there is no need to keep history commits.

Copy link
Copy Markdown
Member Author

A follow-up of the binder bug:
The issue repros without COM enumeration. #4607 opened to track it.

Ilya (iSazonov) merged commit befc5f8 into PowerShell:master Aug 17, 2017

Copy link
Copy Markdown
Collaborator

Dongbo Wang (@daxian-dbw) Merged.
Great work! Thanks!

Copy link
Copy Markdown
Member Author

Ilya (@iSazonov) Thank you for the review and good work as a maintainer 😄

Here are some of my experiences to choose among Squash and merge, Rebase and merge and Create a merge commit:

  1. number of meaningful commits (commits that are part of the PR work, or commits to address major comments that require non-trivial design/logic changes) is one thing to consider
  2. the complexity of the PR work is also something to consider.
  • Some PR may involve many commits, but the fix or feature work is not complex, in those cases, just Squash and merge.
  • Some PR may have clean history commits, but again, the fix/work is simple, in those cases, Squash and merge
  • A PR may be complex work, and the history is not clean -- complex work usually means a lot major changes during the review process -- in such case, choose create a merge commit to preserve the history even though it's not clean. Example: Native pipe #2450
  • A PR is non-trivial and the history is clean, then it's worthy to keep the history. In this case, consider using rebase and merge to keep the main branch history clean if the number of commits is not too many (~5/6). Otherwise, use create a merge commit.
  • A PR may contain more than 1 fix, in this case we usually should ask the author to break it into two PRs.

As you can see from the main branch history, most of time we use (and prefer to) squash and merge.

As for what is a simple/complex/non-trivial fix/work, it's hard to describe but you will have your judgement call as you gain more expeirences.

Copy link
Copy Markdown
Collaborator

Dongbo Wang (@daxian-dbw) Thanks for sharing your experience!

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants


Back | FazBrowse Home | New Git URL