├── .gitignore ├── media ├── icon.png ├── example.gif ├── dark.svg └── light.svg ├── .vscodeignore ├── .vscode ├── extensions.json ├── tasks.json ├── settings.json └── launch.json ├── tsconfig.json ├── .eslintrc.json ├── README.md ├── LICENSE ├── CHANGELOG.md ├── src └── extension.ts └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | -------------------------------------------------------------------------------- /media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrandonXLF/exe-runner/master/media/icon.png -------------------------------------------------------------------------------- /media/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrandonXLF/exe-runner/master/media/example.gif -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | src/** 3 | .eslintrc.json 4 | .gitignore 5 | tsconfig.json 6 | **/*.map 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | "strict": true, 12 | "removeComments": true 13 | }, 14 | "exclude": [ 15 | "node_modules", 16 | ".vscode-test" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/naming-convention": "warn", 13 | "@typescript-eslint/semi": "warn", 14 | "curly": "warn", 15 | "eqeqeq": "warn", 16 | "no-throw-literal": "warn", 17 | "semi": "off" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off", 11 | "svg.preview.background": "custom" 12 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # exe Runner 2 | 3 | Easily run `.exe` files in the Visual Studio Code terminal. Uses a compatibility layer, such as `wine`, on non-Windows platforms. 4 | 5 | ## Features 6 | 7 | * Run the current `.exe` file by clicking the button right of the tab bar 8 | * Run any `.exe` files from their file, editor tab, and editor context menus 9 | * Run the current `.exe` with the command `Run Executable` 10 | * On non-Windows platforms, invoke a compatibility layer, such as `wine`, to run `.exe` files 11 | * Options to clear previous output and to run `.exe` files from their directory 12 | 13 | ## Example 14 | 15 | ![example](media/example.gif) 16 | -------------------------------------------------------------------------------- /media/dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /media/light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ], 15 | "outFiles": [ 16 | "${workspaceFolder}/out/**/*.js" 17 | ], 18 | "preLaunchTask": "${defaultBuildTask}" 19 | }, 20 | { 21 | "name": "Extension Tests", 22 | "type": "extensionHost", 23 | "request": "launch", 24 | "args": [ 25 | "--extensionDevelopmentPath=${workspaceFolder}", 26 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 27 | ], 28 | "outFiles": [ 29 | "${workspaceFolder}/out/test/**/*.js" 30 | ], 31 | "preLaunchTask": "${defaultBuildTask}" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Brandon Fowler 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 1.1.1 4 | 5 | - Use "&" to run executables on PowerShell 6 | 7 | ## 1.1.0 8 | 9 | - "Run Executable" command now works on the unsupported text encoding page 10 | - "exe Runner" terminal now uses a custom icon 11 | 12 | ## 1.0.0 13 | 14 | - No longer force the use of `cmd.exe` on windows when creating the terminal 15 | - Added an option to run `.exe` files in the directory they are located in (`exeRunner.runInFileDirectory`) 16 | - Added an option to clear the terminal before each run (`exeRunner.clearTerminal`) 17 | - Added an option to customize the compatibility layer used in non-Windows environments (`exeRunner.compatibilityLayer`) 18 | - Reuse persistent terminals when `terminal.integrated.enablePersistentSessions` is enabled 19 | 20 | ## 0.2.1 21 | 22 | - "Run Executable" now works as expected from the command palette 23 | 24 | ## 0.2.0 25 | 26 | - Optimized code 27 | - exe Runner terminal is only discarded when it is closed, rather than any terminal 28 | - "Run Executable" added to editor tab context menu 29 | 30 | ## 0.1.0 31 | 32 | - Terminal always uses cmd.exe on windows 33 | - On non-Windows OSes, wine is used 34 | 35 | ## 0.0.2 36 | 37 | - Updated LICENSE filename 38 | 39 | ## 0.0.1 40 | 41 | - Initial release -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import { fileURLToPath } from 'url'; 3 | import { dirname } from 'path'; 4 | 5 | let terminal: vscode.Terminal | undefined; 6 | let extensionUri: vscode.Uri; 7 | 8 | function runExe(fileUri?: vscode.Uri) { 9 | // Fallback to the active tab for command palette 10 | if (!fileUri) { 11 | const tabInput = vscode.window.tabGroups.activeTabGroup.activeTab?.input; 12 | 13 | if ( 14 | tabInput instanceof vscode.TabInputText || 15 | tabInput instanceof vscode.TabInputCustom 16 | ) { 17 | fileUri = tabInput.uri; 18 | } 19 | } 20 | 21 | // Handle remote editors 22 | if (!fileUri || fileUri.scheme !== 'file') { 23 | vscode.window.showErrorMessage('Selected file is an invalid local file.'); 24 | return; 25 | } 26 | 27 | const config = vscode.workspace.getConfiguration('exeRunner'), 28 | filePath = fileURLToPath(fileUri.toString()), 29 | isWin = process.platform === 'win32'; 30 | 31 | // Create a new terminal if an existing one does not exist 32 | terminal = terminal ?? vscode.window.createTerminal({ 33 | name: 'exe Runner', 34 | iconPath: { 35 | light: vscode.Uri.joinPath(extensionUri, 'media', 'light.svg'), 36 | dark: vscode.Uri.joinPath(extensionUri, 'media', 'dark.svg') 37 | } 38 | }); 39 | 40 | if (config.get('clearTerminal')) { 41 | terminal.sendText(isWin ? 'cls' : 'clear'); 42 | } 43 | 44 | terminal.show(); 45 | 46 | let command = ''; 47 | 48 | if (config.get('runInFileDirectory')) { 49 | const directory = dirname(filePath); 50 | command += `cd "${directory}" && `; 51 | } 52 | 53 | // @ts-ignore shellPath doesn't exist on ExtensionTerminalOptions 54 | const shellPath = terminal.creationOptions.shellPath ?? vscode.env.shell; 55 | 56 | // Execute with the & operator when using PowerShell 57 | if (isWin && (shellPath.endsWith('powershell.exe') || shellPath.endsWith('pwsh.exe'))) { 58 | command += '& '; 59 | } else if (!isWin) { 60 | command += config.get('compatibilityLayer') + ' '; 61 | } 62 | 63 | terminal.sendText(`${command}"${filePath}"`); 64 | 65 | // Unset the terminal variable when the terminal is closed 66 | vscode.window.onDidCloseTerminal(closedTerminal => { 67 | if (closedTerminal === terminal) { 68 | terminal = undefined; 69 | } 70 | }); 71 | } 72 | 73 | export function activate(context: vscode.ExtensionContext) { 74 | // Restore persistence terminal 75 | terminal = vscode.window.terminals.find(term => term.name === 'exe Runner'); 76 | extensionUri = context.extensionUri; 77 | 78 | context.subscriptions.push( 79 | vscode.commands.registerCommand('exe-runner.run', runExe) 80 | ); 81 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exe-runner", 3 | "displayName": "exe Runner", 4 | "description": "Run .exe files directly from Visual Studio Code", 5 | "publisher": "brandonfowler", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/BrandonXLF/exe-runner" 10 | }, 11 | "homepage": "https://github.com/BrandonXLF/exe-runner", 12 | "bugs": { 13 | "url": "https://github.com/BrandonXLF/exe-runner/issues" 14 | }, 15 | "icon": "media/icon.png", 16 | "version": "1.1.1", 17 | "engines": { 18 | "vscode": "^1.14.0" 19 | }, 20 | "categories": [ 21 | "Other" 22 | ], 23 | "keywords": [ 24 | "exe", 25 | "executable" 26 | ], 27 | "activationEvents": [ 28 | "onCommand:exe-runner.run" 29 | ], 30 | "main": "./out/extension.js", 31 | "contributes": { 32 | "commands": [ 33 | { 34 | "command": "exe-runner.run", 35 | "title": "Run Executable", 36 | "icon": { 37 | "light": "media/light.svg", 38 | "dark": "media/dark.svg" 39 | } 40 | } 41 | ], 42 | "configuration": { 43 | "title": "exe Runner", 44 | "properties": { 45 | "exeRunner.runInFileDirectory": { 46 | "type": "boolean", 47 | "default": false, 48 | "description": "Run executables with the CWD set to the directory they are located in." 49 | }, 50 | "exeRunner.clearTerminal": { 51 | "type": "boolean", 52 | "default": false, 53 | "description": "Clear the terminal before each exe execution." 54 | }, 55 | "exeRunner.compatibilityLayer": { 56 | "type": "string", 57 | "default": "wine", 58 | "description": "Compatibility layer to use on non-Windows platforms." 59 | } 60 | } 61 | }, 62 | "menus": { 63 | "commandPalette": [ 64 | { 65 | "command": "exe-runner.run", 66 | "when": "resourceExtname == .exe" 67 | } 68 | ], 69 | "editor/title": [ 70 | { 71 | "command": "exe-runner.run", 72 | "group": "navigation", 73 | "when": "resourceExtname == .exe" 74 | } 75 | ], 76 | "editor/title/context": [ 77 | { 78 | "command": "exe-runner.run", 79 | "group": "navigation", 80 | "when": "resourceExtname == .exe" 81 | } 82 | ], 83 | "explorer/context": [ 84 | { 85 | "command": "exe-runner.run", 86 | "group": "navigation", 87 | "when": "resourceExtname == .exe" 88 | } 89 | ], 90 | "editor/context": [ 91 | { 92 | "command": "exe-runner.run", 93 | "group": "navigation", 94 | "when": "resourceExtname == .exe" 95 | } 96 | ] 97 | } 98 | }, 99 | "scripts": { 100 | "vscode:prepublish": "npm run compile", 101 | "compile": "tsc -p ./", 102 | "lint": "eslint src --ext ts", 103 | "watch": "tsc -watch -p ./" 104 | }, 105 | "devDependencies": { 106 | "@types/node": "^12.12.69", 107 | "@types/vscode": "^1.14.0", 108 | "@typescript-eslint/eslint-plugin": "^4.1.1", 109 | "@typescript-eslint/parser": "^4.1.1", 110 | "eslint": "^7.9.0", 111 | "typescript": "^4.0.2" 112 | } 113 | } 114 | --------------------------------------------------------------------------------