1
1
mirror of https://github.com/Eugeny/tabby.git synced 2024-11-22 11:52:03 +03:00

Experimental UAC start-as-admin wrapper (fixes #511)

This commit is contained in:
Eugene Pankov 2018-12-24 18:11:26 +01:00
parent d7b305bf29
commit a7c1fe3425
19 changed files with 342 additions and 4 deletions

BIN
extras/UAC.exe Normal file

Binary file not shown.

View File

@ -21,6 +21,7 @@ export interface SessionOptions {
width?: number
height?: number
pauseAfterExit?: boolean
runAsAdministrator?: boolean
}
export interface Profile {

View File

@ -32,6 +32,13 @@
i.fas.fa-plus.mr-2
| Add
.form-line(*ngIf='uac.isAvailable')
.header
.title Run as administrator
toggle(
[(ngModel)]='profile.sessionOptions.runAsAdministrator',
)
.form-group
label Working directory
input.form-control(

View File

@ -1,5 +1,6 @@
import { Component } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { UACService } from '../services/uac.service'
import { Profile } from '../api'
@Component({
@ -9,6 +10,7 @@ export class EditProfileModalComponent {
profile: Profile
constructor (
public uac: UACService,
private modalInstance: NgbActiveModal,
) {
}

View File

@ -15,7 +15,7 @@ h3.mb-3 Shell
) {{shell.name}}
.form-line(*ngIf='hostApp.platform === Platform.Windows')
.form-line(*ngIf='isConPTYAvailable')
.header
.title Use ConPTY
.description Enables the experimental Windows ConPTY API

View File

@ -5,6 +5,7 @@ import { ConfigService, ElectronService, HostAppService, Platform } from 'termin
import { EditProfileModalComponent } from './editProfileModal.component'
import { IShell, Profile } from '../api'
import { TerminalService } from '../services/terminal.service'
import { UACService } from '../services/uac.service'
@Component({
template: require('./shellSettingsTab.component.pug'),
@ -13,9 +14,11 @@ export class ShellSettingsTabComponent {
shells: IShell[] = []
profiles: Profile[] = []
Platform = Platform
isConPTYAvailable: boolean
private configSubscription: Subscription
constructor (
uac: UACService,
public config: ConfigService,
public hostApp: HostAppService,
private electron: ElectronService,
@ -27,6 +30,7 @@ export class ShellSettingsTabComponent {
this.reload()
})
this.reload()
this.isConPTYAvailable = uac.isAvailable
}
async ngOnInit () {

View File

@ -7,6 +7,7 @@ import { AppService, ConfigService, BaseTabComponent, BaseTabProcess, ElectronSe
import { Session, SessionsService } from '../services/sessions.service'
import { TerminalService } from '../services/terminal.service'
import { TerminalFrontendService } from '../services/terminalFrontend.service'
import { UACService } from '../services/uac.service'
import { TerminalDecorator, ResizeEvent, SessionOptions } from '../api'
import { Frontend } from '../frontends/frontend'
@ -52,6 +53,7 @@ export class TerminalTabComponent extends BaseTabComponent {
private terminalContainersService: TerminalFrontendService,
public config: ConfigService,
private toastr: ToastrService,
private uac: UACService,
@Optional() @Inject(TerminalDecorator) private decorators: TerminalDecorator[],
) {
super()
@ -205,7 +207,7 @@ export class TerminalTabComponent extends BaseTabComponent {
async buildContextMenu (): Promise<Electron.MenuItemConstructorOptions[]> {
let shells = await this.terminalService.shells$.toPromise()
return [
let items: Electron.MenuItemConstructorOptions[] = [
{
label: 'New terminal',
click: () => this.zone.run(() => {
@ -221,6 +223,23 @@ export class TerminalTabComponent extends BaseTabComponent {
}),
})),
},
]
if (this.uac.isAvailable) {
items.push({
label: 'New as admin',
submenu: shells.map(shell => ({
label: shell.name,
click: () => this.zone.run(async () => {
let options = this.terminalService.optionsFromShell(shell)
options.runAsAdministrator = true
this.terminalService.openTabWithOptions(options)
}),
})),
})
}
items = items.concat([
{
label: 'New with profile',
submenu: this.config.store.terminal.profiles.length ? this.config.store.terminal.profiles.map(profile => ({
@ -255,7 +274,9 @@ export class TerminalTabComponent extends BaseTabComponent {
})
}
},
]
])
return items
}
detachTermContainerHandlers () {

View File

@ -3,6 +3,7 @@ import { Injectable, Inject } from '@angular/core'
import { AppService, Logger, LogService, ConfigService } from 'terminus-core'
import { IShell, ShellProvider, SessionOptions } from '../api'
import { TerminalTabComponent } from '../components/terminalTab.component'
import { UACService } from './uac.service'
@Injectable({ providedIn: 'root' })
export class TerminalService {
@ -14,6 +15,7 @@ export class TerminalService {
constructor (
private app: AppService,
private config: ConfigService,
private uac: UACService,
@Inject(ShellProvider) private shellProviders: ShellProvider[],
log: LogService,
) {
@ -61,7 +63,7 @@ export class TerminalService {
return this.openTabWithOptions(sessionOptions)
}
optionsFromShell (shell: IShell) {
optionsFromShell (shell: IShell): SessionOptions {
return {
command: shell.command,
args: shell.args || [],
@ -70,6 +72,9 @@ export class TerminalService {
}
openTabWithOptions (sessionOptions: SessionOptions): TerminalTabComponent {
if (sessionOptions.runAsAdministrator && this.uac.isAvailable) {
sessionOptions = this.uac.patchSessionOptionsForUAC(sessionOptions)
}
this.logger.log('Using session options:', sessionOptions)
return this.app.openNewTab(

View File

@ -0,0 +1,43 @@
import * as path from 'path'
import * as os from 'os'
import { Injectable } from '@angular/core'
import { ElectronService, HostAppService, Platform } from 'terminus-core'
import { SessionOptions } from '../api'
@Injectable({ providedIn: 'root' })
export class UACService {
isAvailable = false
constructor (
hostApp: HostAppService,
private electron: ElectronService,
) {
this.isAvailable = hostApp.platform === Platform.Windows
&& parseFloat(os.release()) >= 10
&& parseInt(os.release().split('.')[2]) >= 17692
}
patchSessionOptionsForUAC (sessionOptions: SessionOptions): SessionOptions {
let helperPath = path.join(
path.dirname(this.electron.app.getPath('exe')),
'resources',
'extras',
'UAC.exe',
)
if (process.env.DEV) {
helperPath = path.join(
path.dirname(this.electron.app.getPath('exe')),
'..', '..', '..',
'extras',
'UAC.exe',
)
}
let options = { ...sessionOptions }
options.args = [options.command, ...options.args]
options.command = helperPath
return options
}
}

4
terminus-uac/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
Debug
*.ipch
*.suo
v15

31
terminus-uac/UAC.sln Normal file
View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27703.2042
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UAC", "UAC\UAC.vcxproj", "{DCE3B955-DB20-4334-B11B-F6C040825A59}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DCE3B955-DB20-4334-B11B-F6C040825A59}.Debug|x64.ActiveCfg = Debug|x64
{DCE3B955-DB20-4334-B11B-F6C040825A59}.Debug|x64.Build.0 = Debug|x64
{DCE3B955-DB20-4334-B11B-F6C040825A59}.Debug|x86.ActiveCfg = Debug|Win32
{DCE3B955-DB20-4334-B11B-F6C040825A59}.Debug|x86.Build.0 = Debug|Win32
{DCE3B955-DB20-4334-B11B-F6C040825A59}.Release|x64.ActiveCfg = Release|x64
{DCE3B955-DB20-4334-B11B-F6C040825A59}.Release|x64.Build.0 = Release|x64
{DCE3B955-DB20-4334-B11B-F6C040825A59}.Release|x86.ActiveCfg = Release|Win32
{DCE3B955-DB20-4334-B11B-F6C040825A59}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {77F43A07-B912-4CCD-9928-5C12F6D0112B}
EndGlobalSection
EndGlobal

BIN
terminus-uac/UAC/UAC.cpp Normal file

Binary file not shown.

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{DCE3B955-DB20-4334-B11B-F6C040825A59}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>UAC</RootNamespace>
<WindowsTargetPlatformVersion>10.0.18298.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="UAC.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UAC.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommandArguments>cmd.exe</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="requireAdministrator"
uiAccess="true" />
</requestedPrivileges>
</security>
</trustInfo>
</asmv1:assembly>

BIN
terminus-uac/UAC/stdafx.cpp Normal file

Binary file not shown.

BIN
terminus-uac/UAC/stdafx.h Normal file

Binary file not shown.

Binary file not shown.