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

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)