Skip to content

Commit db370dc

Browse files
authored
Enable pwsh to work on Windows systems where mpr.dll and STA is not available (PowerShell#11748)
1 parent 127fec5 commit db370dc

2 files changed

Lines changed: 68 additions & 6 deletions

File tree

src/Microsoft.PowerShell.ConsoleHost/WindowsTaskbarJumpList/TaskbarJumpList.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,16 @@ internal static void CreateRunAsAdministratorJumpList()
4242
Debug.Fail($"Creating 'Run as Administrator' JumpList failed. {exception}");
4343
}
4444
});
45-
thread.SetApartmentState(ApartmentState.STA);
46-
thread.Start();
45+
46+
try
47+
{
48+
thread.SetApartmentState(ApartmentState.STA);
49+
thread.Start();
50+
}
51+
catch (System.Threading.ThreadStartException)
52+
{
53+
// STA may not be supported on some platforms
54+
}
4755
}
4856

4957
private static void CreateElevatedEntry(string title)

src/System.Management.Automation/namespaces/FileSystemProvider.cs

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,8 @@ private void MapNetworkDrive(PSDriveInfo drive)
598598
}
599599
}
600600

601+
private static bool _WNetApiAvailable = true;
602+
601603
private void WinMapNetworkDrive(PSDriveInfo drive)
602604
{
603605
if (drive != null && !string.IsNullOrEmpty(drive.Root))
@@ -608,6 +610,7 @@ private void WinMapNetworkDrive(PSDriveInfo drive)
608610
const int RESOURCETYPE_ANY = 0x00000000;
609611
const int RESOURCEDISPLAYTYPE_GENERIC = 0x00000000;
610612
const int RESOURCEUSAGE_CONNECTABLE = 0x00000001;
613+
const int ERROR_NO_NETWORK = 1222;
611614

612615
// By default the connection is not persisted.
613616
int CONNECT_TYPE = CONNECT_NOPERSIST;
@@ -652,7 +655,19 @@ private void WinMapNetworkDrive(PSDriveInfo drive)
652655
resource.Type = RESOURCETYPE_ANY;
653656
resource.Usage = RESOURCEUSAGE_CONNECTABLE;
654657

655-
int code = NativeMethods.WNetAddConnection2(ref resource, passwd, userName, CONNECT_TYPE);
658+
int code = ERROR_NO_NETWORK;
659+
660+
if (_WNetApiAvailable)
661+
{
662+
try
663+
{
664+
code = NativeMethods.WNetAddConnection2(ref resource, passwd, userName, CONNECT_TYPE);
665+
}
666+
catch (System.DllNotFoundException)
667+
{
668+
_WNetApiAvailable = false;
669+
}
670+
}
656671

657672
if (code != 0)
658673
{
@@ -717,6 +732,7 @@ private PSDriveInfo WinRemoveDrive(PSDriveInfo drive)
717732
if (IsNetworkMappedDrive(drive))
718733
{
719734
const int CONNECT_UPDATE_PROFILE = 0x00000001;
735+
const int ERROR_NO_NETWORK = 1222;
720736

721737
int flags = 0;
722738
string driveName;
@@ -734,7 +750,19 @@ private PSDriveInfo WinRemoveDrive(PSDriveInfo drive)
734750
}
735751

736752
// You need to actually remove the drive.
737-
int code = NativeMethods.WNetCancelConnection2(driveName, flags, true);
753+
int code = ERROR_NO_NETWORK;
754+
755+
if (_WNetApiAvailable)
756+
{
757+
try
758+
{
759+
code = NativeMethods.WNetCancelConnection2(driveName, flags, true);
760+
}
761+
catch (System.DllNotFoundException)
762+
{
763+
_WNetApiAvailable = false;
764+
}
765+
}
738766

739767
if (code != 0)
740768
{
@@ -787,6 +815,7 @@ internal static string GetUNCForNetworkDrive(string driveName)
787815

788816
private static string WinGetUNCForNetworkDrive(string driveName)
789817
{
818+
const int ERROR_NO_NETWORK = 1222;
790819
string uncPath = null;
791820
if (!string.IsNullOrEmpty(driveName) && driveName.Length == 1)
792821
{
@@ -803,7 +832,16 @@ private static string WinGetUNCForNetworkDrive(string driveName)
803832
driveName += ':';
804833

805834
// Call the windows API
806-
int errorCode = NativeMethods.WNetGetConnection(driveName, uncBuffer, ref bufferSize);
835+
int errorCode = ERROR_NO_NETWORK;
836+
837+
try
838+
{
839+
errorCode = NativeMethods.WNetGetConnection(driveName, uncBuffer, ref bufferSize);
840+
}
841+
catch (System.DllNotFoundException)
842+
{
843+
return null;
844+
}
807845

808846
// error code 234 is returned whenever the required buffer size is greater
809847
// than the specified buffer size.
@@ -7102,6 +7140,8 @@ private static class NativeMethods
71027140
[DllImport("api-ms-win-core-shlwapi-legacy-l1-1-0.dll", CharSet = CharSet.Unicode)]
71037141
internal static extern int PathGetDriveNumber(string path);
71047142

7143+
private static bool _WNetApiAvailable = true;
7144+
71057145
/// <summary>
71067146
/// The API 'PathIsNetworkPath' is not available in CoreSystem.
71077147
/// This implementation is based on the 'PathIsNetworkPath' API.
@@ -7120,6 +7160,11 @@ internal static bool PathIsNetworkPath(string path)
71207160
return true;
71217161
}
71227162

7163+
if (!_WNetApiAvailable)
7164+
{
7165+
return false;
7166+
}
7167+
71237168
// 0 - 25 corresponding to 'A' - 'Z'
71247169
int driveId = PathGetDriveNumber(path);
71257170
if (driveId >= 0 && driveId < 26)
@@ -7128,7 +7173,16 @@ internal static bool PathIsNetworkPath(string path)
71287173

71297174
int bufferSize = 260; // MAX_PATH from EhStorIoctl.h
71307175
StringBuilder uncBuffer = new StringBuilder(bufferSize);
7131-
int errorCode = WNetGetConnection(driveName, uncBuffer, ref bufferSize);
7176+
int errorCode = -1;
7177+
try
7178+
{
7179+
errorCode = WNetGetConnection(driveName, uncBuffer, ref bufferSize);
7180+
}
7181+
catch (System.DllNotFoundException)
7182+
{
7183+
_WNetApiAvailable = false;
7184+
return false;
7185+
}
71327186

71337187
// From the 'IsNetDrive' API.
71347188
// 0: success; 1201: connection closed; 31: device error

0 commit comments

Comments
 (0)