windowsStock.ts 2.7 KB
Newer Older
E
Eugene Pankov 已提交
1
import * as path from 'path'
E
Eugene Pankov 已提交
2 3 4
import * as fs from 'fs/promises'
import hasbin from 'hasbin'
import { promisify } from 'util'
E
Eugene Pankov 已提交
5
import { Injectable } from '@angular/core'
E
Eugene Pankov 已提交
6 7
import { HostAppService, Platform } from 'tabby-core'
import { ElectronService } from 'tabby-electron'
E
Eugene Pankov 已提交
8

9
import { ShellProvider, Shell } from '../api'
E
Eugene Pankov 已提交
10

E
Eugene Pankov 已提交
11
/** @hidden */
E
Eugene Pankov 已提交
12 13 14 15 16 17 18 19 20
@Injectable()
export class WindowsStockShellsProvider extends ShellProvider {
    constructor (
        private hostApp: HostAppService,
        private electron: ElectronService,
    ) {
        super()
    }

E
Eugene Pankov 已提交
21
    async provide (): Promise<Shell[]> {
E
Eugene Pankov 已提交
22 23 24
        if (this.hostApp.platform !== Platform.Windows) {
            return []
        }
E
Eugene Pankov 已提交
25 26 27 28 29 30 31 32 33

        let clinkPath = path.join(
            path.dirname(this.electron.app.getPath('exe')),
            'resources',
            'extras',
            'clink',
            `clink_${process.arch}.exe`,
        )

E
Eugene Pankov 已提交
34
        if (process.env.TABBY_DEV) {
E
Eugene Pankov 已提交
35 36 37 38 39 40 41 42
            clinkPath = path.join(
                path.dirname(this.electron.app.getPath('exe')),
                '..', '..', '..',
                'extras',
                'clink',
                `clink_${process.arch}.exe`,
            )
        }
E
Eugene Pankov 已提交
43 44 45 46 47
        return [
            {
                id: 'clink',
                name: 'CMD (clink)',
                command: 'cmd.exe',
E
Eugene Pankov 已提交
48 49 50 51 52
                args: ['/k', clinkPath, 'inject'],
                env: {
                    // Tell clink not to emulate ANSI handling
                    WT_SESSION: '0',
                },
53
                icon: require('../icons/clink.svg'),
E
Eugene Pankov 已提交
54 55 56 57 58 59
            },
            {
                id: 'cmd',
                name: 'CMD (stock)',
                command: 'cmd.exe',
                env: {},
60
                icon: require('../icons/cmd.svg'),
E
Eugene Pankov 已提交
61
            },
E
Eugene Pankov 已提交
62 63
            {
                id: 'powershell',
64
                name: 'PowerShell',
E
Eugene Pankov 已提交
65
                command: await this.getPowerShellPath(),
66
                args: ['-nologo'],
67
                icon: require('../icons/powershell.svg'),
E
Eugene Pankov 已提交
68 69
                env: {
                    TERM: 'cygwin',
E
Eugene Pankov 已提交
70
                },
E
Eugene Pankov 已提交
71
            },
E
Eugene Pankov 已提交
72 73
        ]
    }
E
Eugene Pankov 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

    private async getPowerShellPath () {
        const ps = 'powershell.exe'

        if (!await promisify(hasbin)(ps)) {
            for (const searchPath of [
                `${process.env.SystemRoot}\\System32\\WindowsPowerShell\\v1.0`,
                `${process.env.SystemRoot}\\System32`,
                process.env.SystemRoot ?? 'C:\\Windows',
            ]) {
                const newPath = path.join(searchPath, ps)
                try {
                    await fs.stat(newPath)
                    return newPath
                } catch { }
            }
        }
        return ps
    }
E
Eugene Pankov 已提交
93
}