Run Elevated Cmd.exe as command

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
lexvictory
Addict
Addict
Posts: 1027
Joined: Sun May 15, 2005 5:15 am
Location: Australia
Contact:

Run Elevated Cmd.exe as command

Post by lexvictory »

Ever been working with Cmd and needed to start an elevated instance?
This aims to remove the need to use the start menu / taskbar to do that; it runs the same as if you typed cmd.exe into the already running cmd. (I'm not sure if there has ever been anything like it)
It can also run standalone (double clicking from explorer, etc)

My original purpose for this is so I can run an elevated cmd in Console2, without having to run another instance of Console2 in elevated mode. (i.e. set it as a shell, then make a new tab selecting it, then it prompts for elevation and runs in the non elevated Console2's window/tab)

Currently it doesnt support any parameters to the cmd.exe that it launches, but you're all programmers so it shouldn't be too hard to edit it yourselves :)
At first I was messing around with pipes and Read/WriteFile_, but then I discovered AttachConsole_(); could not have been simpler really :lol:
Compile it with the Request User Mode option; it runs itself again as elevated.

If you need clarification let me know.

Code: Select all

#admin_CommandFlag = "/admin"
#SEE_MASK_UNICODE = $00004000
Global  pipe_hProcess

Procedure RunProgramAdminHandle(windowid, exe.s, params.s, workingdir.s)
  Protected shellex.SHELLEXECUTEINFO
  shellex\cbSize = SizeOf(SHELLEXECUTEINFO)
  shellex\fMask = #SEE_MASK_NOCLOSEPROCESS
  CompilerIf #PB_Compiler_Unicode
    shellex\fMask = shellex\fMask|#SEE_MASK_UNICODE
  CompilerEndIf
  shellex\hwnd = windowid
  If OSVersion() >= #PB_OS_Windows_Vista
    shellex\lpVerb = @"runas"
  EndIf 
  shellex\lpFile = @exe
  shellex\lpParameters = @params
  shellex\lpDirectory = @workingdir
  CompilerIf #PB_Compiler_Debugger
    shellex\nShow = #SW_SHOW
  CompilerElse
    shellex\nShow = #SW_HIDE
  CompilerEndIf
  ShellExecuteEx_(shellex)
  ProcedureReturn shellex\hProcess
EndProcedure

Procedure ProcessRunning(hProcess)
  Protected exitcode.l
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows 
  GetExitCodeProcess_(hProcess, @exitcode)
  If exitcode = #STILL_ACTIVE
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf 
  CompilerElse
    ProcedureReturn ProgramRunning(hProcess)
  CompilerEndIf
EndProcedure

If ProgramParameter(0) = #admin_CommandFlag
  CompilerIf #PB_Compiler_Debugger
    Import ""
      PB_DEBUGGER_SendWarning(Message.p-ascii)
    EndImport
    PB_DEBUGGER_SendWarning("I am the admin mode client instance");this is so you can tell which debugger is running the client
  CompilerEndIf
  
  import ""
    AttachConsole(dwProcessId)
  EndImport
  
  FreeConsole_()
  AttachConsole(val(ProgramParameter(1)))
  
  RunProgram("cmd", "", GetCurrentDirectory(), #PB_Program_Wait)
  End 
EndIf 

OpenConsole()

CompilerIf #PB_Compiler_Debugger;-this will interfere with the process running checks. disable it (put "0 or" in front of the constant) to let the check work
  pipe_hProcess = RunProgramAdminHandle(GetForegroundWindow_(), #PB_Compiler_Home+"compilers\pbdebuggerunicode.exe", #DQUOTE$+ProgramFilename()+#DQUOTE$+" "+#admin_CommandFlag+" "+str(GetCurrentProcessId_()), GetCurrentDirectory());we run the debugger, because otherwise if you start a console app, like cmd.exe, it will inherit the console debugger's console.
CompilerElse
  pipe_hProcess = RunProgramAdminHandle(GetForegroundWindow_(), ProgramFilename(), #admin_CommandFlag+" "+str(GetCurrentProcessId_()), GetCurrentDirectory())
CompilerEndIf

if pipe_hProcess
  while ProcessRunning(pipe_hProcess)
    Delay(20)
  wend
else
  debug "pipe_hprocess empty"
endif

CloseHandle_(pipe_hProcess)
Demonio Ardente

Currently managing Linux & OS X Tailbite
OS X TailBite now up to date with Windows!