8000 Make ShellExecuteEx use STA by SteveL-MSFT · Pull Request #4362 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

Make ShellExecuteEx use STA #4362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send yo 8000 u account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 1, 2017
Merged

Conversation

SteveL-MSFT
Copy link
Member

fix shellexecuteex call to use STA as recommended by MSDN
also removed some FullCLR code (left the TODO as it's a bigger item)

Fix #2969

@@ -106,6 +106,7 @@ Describe "Start-Process" -Tags @("CI","SLOW") {
}

It "Should open the application that associates with extension '.txt'" -Skip:(!$isFullWin) {
"c:\windows\system32\notepad.exe" | Should Exist
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suggest use %WINDIR%.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ignore this for now, trying to figure out why the test succeeds on my machine but fails in AppVeyor

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 as part of #4353

throw new Win32Exception(errorCode);
}
Thread thread = new Thread(InvokeShellExecuteEx);
thread.SetApartmentState(System.Threading.ApartmentState.STA);
Copy link
Member

Choose a reason for hiding this comment

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

We should check if the current thread is STA already. If so, invoke the method without creating a new thread.

Copy link
Member Author

Choose a reason for hiding this comment

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

will fix

if (!NativeMethods.ShellExecuteEx(shellExecuteInfo))
{
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == 0)
Copy link
Member

Choose a reason for hiding this comment

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

The error handling code needs to happen in the main thread, otherwise, the Win32Exception thrown from here will be ignored.

Copy link
Member Author

Choose a reason for hiding this comment

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

will fix

Thread thread = new Thread(InvokeShellExecuteEx);
thread.SetApartmentState(System.Threading.ApartmentState.STA);
thread.Start(shellExecuteInfo);
thread.Join();
Copy link
Member

Choose a reason for hiding this comment

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

The Win32Exception thrown from the new thread will probably be ignored. We should handle the error in the main thread.
Please take a look at the .NET implementation at https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Process.cs,2239
The ShellExecuteOnSTAThread method is defined at https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Process.cs,2856

Copy link
Member Author

Choose a reason for hiding this comment

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

will fix

/// <summary>
/// Helper to start process using ShellExecuteEx. This is used only in PowerShell Core on Full Windows.
/// </summary>
internal class ShellExecuteHelper
{
private static bool _succeeded;
private static int _errorCode;
Copy link
Member

Choose a reason for hiding this comment

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

These 2 static fields will cause race condition when multiple Runsapces are running ShellExecuteHelper.Start at the same time. Using a helper class like in .NET implementation may be a better approach.

Copy link
Member Author

Choose a reason for hiding this comment

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

will fix

@@ -1719,6 +1591,56 @@ internal static Process Start(ProcessStartInfo startInfo, ProcessWindowStyle win
return processToReturn;
}

private void ShellExecuteFunction() {
Copy link
Member

Choose a reason for hiding this comment

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

Please use the existing style -- put the open parenthesis on a new line.

{
ShellExecuteFunction();
}
return _succeeded;
Copy link
Member

Choose a reason for hiding this comment

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

_succeeded is never set to true. Maybe you can set its default value to true, or you can use similar way as in https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Process.cs,2850

Copy link
Member Author

Choose a reason for hiding this comment

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

missed that, will fix

@daxian-dbw daxian-dbw merged commit e38f0e7 into PowerShell:master Aug 1, 2017
@SteveL-MSFT SteveL-MSFT deleted the startprocess branch August 1, 2017 18:31
progFileDir = Path.Combine(appBase, "Modules");
#else
progFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "WindowsPowerShell", "Modules");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't we want load Windows PowerShell Modules from %ProgramFiles%\WindowsPowerShell? Currently we use PSModulePath as first step solution.

685C

Copy link
Member Author

Choose a reason for hiding this comment

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

We'll have a different solution for supporting Windows PowerShell PSModulePath in PSCore6 that replaces the current interim solution

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.

powershell should run ShellExecuteEx on STA thread
4 participants
0