Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Clean up ShellExecute code to use the .NET Core implementation#4523

Merged
adityapatwardhan merged 7 commits into
PowerShell:masterPowerShell/PowerShell:masterfrom
daxian-dbw:shellexecutedaxian-dbw/PowerShell:shellexecuteCopy head branch name to clipboard
Aug 10, 2017
Merged

Clean up ShellExecute code to use the .NET Core implementation#4523
adityapatwardhan merged 7 commits into
PowerShell:masterPowerShell/PowerShell:masterfrom
daxian-dbw:shellexecutedaxian-dbw/PowerShell:shellexecuteCopy head branch name to clipboard

Conversation

@daxian-dbw

@daxian-dbw daxian-dbw commented Aug 7, 2017

Copy link
Copy Markdown
Member

Fix #4499

This PR includes following major changes:

  1. ProcessStartInfo.UseShellExecute is now supported in .NET Core on Windows. So we need to remove our implementation of ShellExecute and use the .NET Core API directly.
  2. Enable NativeCommandProcessor to open files using default program associated with the shell.
  3. Fix NativeCommandProcessor to properly clean up in case an exception is thrown in Prepare and ProcessRecord.

Note that, UseShellExecute works as full .NET on windows desktop, but it doesn't work properly on Unix and the improvement work is tracked by dotnet/corefx#19956. So on Linux/OSX, we still need to rely on xdg-open/open


// -Verb and -WindowStyle are not supported on non-Windows platforms as well as Windows headless SKUs
if (_isOnFullWinSku)
if (Platform.IsWindowsDesktop)

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.

Maybe cache the value in a variable instead of looking it up twice in the same method.

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.

Updated the code to cache the value in Platform.IsWindowsDesktop.

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.

@daxian-dbw This does not seem to be fixed.

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.

The value is cached in a static field in Platform.IsWindowsDesktop property.

#else
ShellExecuteHelper.Start(invokeProcess.StartInfo);
// Use ShellExecute when it's not a headless SKU
invokeProcess.StartInfo.UseShellExecute = !Platform.IsNanoServer && !Platform.IsIoT;

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.

Can we use Platform.IsWindowsDesktop here?

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.

Sure. Will update the code.

xdg-mime default nativeCommandProcessor.desktop text/plain
}
}
elseif ($IsWindows) {

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.

We can use Platform.IsWindowsDesktop if it is made public.

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.

Good point. Will update.

& $dllFile
throw "No Exception!"
} catch {
$_.FullyQualifiedErrorId | should be "NativeCommandFailed"

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.

Use ShouldBeErroId. Example :

{ & $testdrive/test.ps1 } | ShouldBeErrorId "Argument"

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.

Fixed.

}
}

internal static bool IsWindowsDesktop

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.

Should we consider making this public? This will be very useful in tests.

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.

Done.

& $TestFile
$startTime = Get-Date
# It may take time for handler to start
while (((Get-Date) - $startTime).TotalSeconds -lt 10 -and (-not (Test-Path "$HOME/nativeCommandProcessor.Success"))) {

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.

Polling for a file can be a common pattern. Consider implementing a generic file watcher function in HelpersCommon.psm1

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.

Sounds reasonable. Opened #4524. Will address in a separate PR.

Get-Process -Name notepad | Stop-Process -Force
Invoke-Item -Path $notepad
$notepadProcess = Get-Process -Name notepad
$notepadProcess.Name | Should Be notepad

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.

Maybe use quotas - "notepad"?

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.

OK, will update.

Invoke-Item -Path $notepad
$notepadProcess = Get-Process -Name notepad
$notepadProcess.Name | Should Be notepad
Stop-Process -InputObject $notepadProcess

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.

Should we move this in AfterAll?

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.

I think it should stay here, as it's specific to this test when running on full desktop.

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.

I don't like commands after Should 😄

@daxian-dbw

Copy link
Copy Markdown
Member Author

There are 2 failures in AppVeyor feature test run and both are related to Invoke-RestMethod, not related to the changes made in this PR. So the feature test run is good.

@daxian-dbw

Copy link
Copy Markdown
Member Author

@adityapatwardhan @iSazonov Your comments have been addressed. Please take another look. Thanks!


// -Verb and -WindowStyle are not supported on non-Windows platforms as well as Windows headless SKUs
if (_isOnFullWinSku)
if (Platform.IsWindowsDesktop)

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.

@daxian-dbw This does not seem to be fixed.

@adityapatwardhan adityapatwardhan left a comment

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.

LGTM

@daxian-dbw daxian-dbw changed the title Shellexecute Clean up ShellExecute code to use the .NET Core implementation Aug 8, 2017

@iSazonov iSazonov left a comment

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.

Since the PR is a cleanup we could add fix - we use "UseShellExecute" constant three times in Process.cs and could move it to private static variable.

}
catch (Exception)
{
// Do the cleanup and rethrow the 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.

It is obvious comment. Please add in the comment why we do this.

@daxian-dbw daxian-dbw Aug 9, 2017

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.

Fixed. More comment added to Cleanup() to explain what we are cleaning up.

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.

Closed.

this.Command.Context.EngineHostInterface.NotifyEndApplication();
}
// Do the clean up...
// Do the cleanup...

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.

Again obvious comment. Please remove or enhance.

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.

Fixed.

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.

Closed.

#else
if (Platform.IsNanoServer)
return false;
if (!Platform.IsWindowsDesktop) { return false; }

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.

Formatting - Can we use the one line pattern for if?

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.

Yes, as long as the if block is a single simple statement like this one.

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.

Closed.

Get-Process -Name notepad | Stop-Process -Force
Invoke-Item -Path $notepad
$notepadProcess = Get-Process -Name notepad
$notepadProcess.Name | Should Be "notepad"

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.

We use "notepad" in three lines (66, 68, 69 and maybe 65) so maybe use a variable?

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.

Fixed.

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.

Closed.

@daxian-dbw

Copy link
Copy Markdown
Member Author

The "Default" constant string is used in 9 places and should be cleaned too (change to const variable, instead of static). But I think they should be in separate PRs as they will introduce too many diffs and make it hard to see the focus of this PR.

@adityapatwardhan adityapatwardhan left a comment

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.

LGTM

@iSazonov

Copy link
Copy Markdown
Collaborator

LGTM.

@daxian-dbw

Copy link
Copy Markdown
Member Author

@iSazonov @adityapatwardhan Thanks for the review! Aditya, can you please merge this PR? My follow-up work on the file watcher test helper needs to update the tests in this PR (#4524).

@adityapatwardhan adityapatwardhan merged commit 384a9fe into PowerShell:master Aug 10, 2017
@daxian-dbw daxian-dbw deleted the shellexecute branch August 10, 2017 20:47
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.

4 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.