@@ -218,3 +218,54 @@ def accepted_kwargs(
218
218
return kwargs
219
219
param_names = set (inspect .signature (func ).parameters .keys ())
220
220
return {k : v for k , v in kwargs .items () if k in param_names }
221
+
222
+
223
+ def get_win_shell () -> str :
224
+ """
225
+ The way installed python scripts are wrapped on Windows means shellingham will detect
226
+ cmd.exe as the shell. This function will attempt to detect the correct shell, usually
227
+ either powershell (<=v5) or pwsh (>=v6).
228
+
229
+ :raises ShellDetectionFailure: If the shell cannot be detected
230
+ :return: The name of the shell, either 'powershell' or 'pwsh'
231
+ """
232
+ import json
233
+ import platform
234
+ import subprocess
235
+
236
+ from shellingham import ShellDetectionFailure
237
+
238
+ assert platform .system () == "Windows"
239
+ pwsh = shutil .which ("pwsh" )
240
+ powershell = shutil .which ("powershell" )
241
+ if pwsh and not powershell :
242
+ return "pwsh"
243
+ elif powershell and not pwsh :
244
+ return "powershell"
245
+ try :
246
+ ps_command = """
247
+ $parent = Get-CimInstance -Query "SELECT * FROM Win32_Process WHERE ProcessId = {pid}";
248
+ $parentPid = $parent.ParentProcessId;
249
+ $parentInfo = Get-CimInstance -Query "SELECT * FROM Win32_Process WHERE ProcessId = $parentPid";
250
+ $parentInfo | Select-Object Name, ProcessId | ConvertTo-Json -Depth 1
251
+ """
252
+ pid = os .getpid ()
253
+ while True :
254
+ result = subprocess .run (
255
+ ["pwsh" , "-NoProfile" , "-Command" , ps_command .format (pid = pid )],
256
+ capture_output = True ,
257
+ text = True ,
258
+ ).stdout .strip ()
259
+ if not result :
260
+ break
261
+ process = json .loads (result )
262
+ if "pwsh" in process .get ("Name" , "" ):
263
+ return "pwsh"
264
+ elif "powershell" in process .get ("Name" , "" ):
265
+ return "powershell"
266
+ pid = process ["ProcessId" ]
267
+
268
+ raise ShellDetectionFailure ("Unable to detect windows shell" )
269
+
270
+ except Exception as e :
271
+ raise ShellDetectionFailure ("Unable to detect windows shell" ) from e
0 commit comments