44import subprocess
55import ctypes
66import re
7+ import shlex
78
89from PyQt5 .QtCore import Qt
910from PyQt5 .QtWidgets import (
@@ -675,15 +676,15 @@ def on_execute_clicked(self):
675676 def run_selected_command (self ):
676677 selected_items = self .table .selectedItems ()
677678 if not selected_items :
678- return # no selection
679+ return # No selection
679680
680681 row = selected_items [0 ].row ()
681682 shortcut , original_index = self .displayed_pairs [row ]
682683
683684 command = shortcut .get ("command" , "" ).strip ()
684685 requires_input = shortcut .get ("requires_input" , False )
685686
686- # If it has placeholders, handle them
687+ # 1) Placeholder handling
687688 if requires_input :
688689 placeholders = re .findall (r"{(.*?)}" , command )
689690 if placeholders :
@@ -692,23 +693,52 @@ def run_selected_command(self):
692693 if not val :
693694 self .info_label .setText ("Command cancelled or no input provided." )
694695 return
696+ # Replace placeholders
695697 command = command .replace (f"{{{ ph } }}" , val )
696698
697- # Determine if it's PowerShell, PS1, .exe, or default to cmd
698- if command .lower ().endswith (".exe" ):
699- # Just run it via subprocess
700- full_cmd = [command ]
701- elif command .lower ().startswith ("powershell" ) or command .lower ().endswith (".ps1" ):
702- full_cmd = ["powershell.exe" , "-NoExit" , "-Command" , command ]
699+ # 2) Parse the final command string into tokens with shlex
700+ try :
701+ tokens = shlex .split (command )
702+ except ValueError as e :
703+ # If there's a quoting error, or user typed something unparseable
704+ self .info_label .setText (f"Shlex parse error: { e } " )
705+ return
706+
707+ if not tokens :
708+ self .info_label .setText ("No command tokens found." )
709+ return
710+
711+ # For debugging: print(tokens)
712+ print ("Parsed tokens:" , tokens )
713+
714+ # 3) Decide how to run
715+ first_token_lower = tokens [0 ].lower ()
716+
717+ # A) If first token ends with .exe, run it directly
718+ if first_token_lower .endswith (".exe" ):
719+ full_cmd = tokens # e.g. ["E:\\HwInfo64.exe", "--someArg"]
720+ # B) If first token is powershell.exe or second token is .ps1, run powershell
721+ elif first_token_lower .startswith ("powershell" ) or (len (tokens ) > 0 and tokens [0 ].lower ().endswith (".ps1" )):
722+ # If user typed "powershell.exe ..." => just use tokens as-is
723+ full_cmd = tokens
724+ # If you want to enforce something like "powershell.exe -NoExit", you can insert tokens here
725+ elif (len (tokens ) > 1 and tokens [1 ].lower ().endswith (".ps1" )):
726+ # e.g. user typed "powershell -File something.ps1"
727+ full_cmd = tokens
703728 else :
704- full_cmd = ["cmd.exe" , "/k" , command ]
729+ # C) Default: pass tokens to cmd /k
730+ # i.e. run cmd, /k, and then your tokens as arguments
731+ full_cmd = ["cmd.exe" , "/k" ] + tokens
732+
733+ print ("Final cmd to execute:" , full_cmd )
705734
735+ # 4) Execute
706736 try :
707- subprocess .Popen (full_cmd , shell = True )
737+ subprocess .Popen (full_cmd , shell = False )
708738 except Exception as e :
739+ print (f"Error executing command: { full_cmd } , Error: { e } " )
709740 self .info_label .setText (f"Error executing: { e } " )
710741
711-
712742 def prompt_for_variable (self , placeholder_label : str = "value" ):
713743 text , ok = QInputDialog .getText (
714744 self ,
0 commit comments