Skip to content

Conversation

@daxian-dbw
Copy link
Member

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

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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Member

@adityapatwardhan adityapatwardhan left a comment

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
Copy link
Collaborator

@iSazonov iSazonov left a comment

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
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.

Copy link
Member Author

@daxian-dbw daxian-dbw Aug 9, 2017

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
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
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
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
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
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
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
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
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
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
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
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.

Copy link
Member

@adityapatwardhan adityapatwardhan left a comment

Choose a reason for hiding this comment

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

LGTM

@iSazonov
Copy link
Collaborator

LGTM.

@daxian-dbw
Copy link
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