Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Andhika Wibawa committed Jun 8, 2021
0 parents commit 0d51a1b
Show file tree
Hide file tree
Showing 33 changed files with 1,116 additions and 0 deletions.
339 changes: 339 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

110 changes: 110 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# VSCodePortable

Visual Studio Code in [PortableApps.com](https://portableapps.com/) format (unofficial). Can possibly be applied to VSCodium too.

# Q&A

### Why do I need it if Visual Studio Code already support native [portable](https://code.visualstudio.com/docs/editor/portable) mode?

Native portable mode can still leave some traces on the system and registry (although the total may be less than 1 MB). Moreover, you still need to add your (portable) development environments to `PATH` manually and sometimes, this process is tiring, especially if you want to set them up on multiple computer or need to change the `PATH` oftenly.

With VSCodePortable, you can just pack your development environments together (along with VSCodePortable), copy them to flash drive, and run them again on different computer without needing to setup them again (see below for more details).

### What are the differences compared to native portable mode?

* All known traces (on the system and registry) will be removed automatically after run. Including some traces left by extensions and development environments. Check `VSCodePortable.ini` and `Custom.nsh` file in `App\AppInfo\Launcher` folder for more details.
* Support some popular development environments (i.e. Git, MinGW, Python, Java, Node.js, and Go), they will be added to `PATH` automatically during runtime. Only affects `Code.exe` and processes run by it, your real `PATH` environment variable will stay untouched. You can specify their location by modifying `VSCodePortable.ini` file in root directory (appears after first run).
* Added context menu items (e.g. `Open with Code`) just like the non-portable version. Will be removed automatically after you close Visual Studio Code (please don't shutdown your system directly, close Visual Studio Code first).
* Can auto-install VSIX files located in `App\FirstRun\VSCode\extensions` folder on first run. Be aware that some extensions require other extension as dependency, you can add number in front of the file name because they will be installed in descending order.

### Why not use VSCodium as the base instead?

VSCodium is not allowed to use any [proprietary debugging tools](https://github.com/VSCodium/vscodium/blob/master/DOCS.md#proprietary-debugging-tools) made by Microsoft. Including those that are embedded on extensions like [C/C++ extension](https://github.com/Microsoft/vscode-cpptools/issues/21#issuecomment-248349017), and many more extensions. _I use some of the proprietary extensions, sorry_.

### What are the differences between this and Gareth Flower's [vscode-portable](https://github.com/garethflowers/vscode-portable)?

As far as I know, Flower's version has similar behavior compared to native portable mode. My version has some extra features that I needed personally (you have seen them on earlier points).

# Other Notes

### How to use?

1. Download the latest [release](https://github.com/AndhikaWB/VSCodePortable/releases) of VSCodePortable
2. Extract it anywhere (e.g. `D:\Apps\VSCodePortable`), avoid using long path
2. Download Visual Studio Code (`.zip` format) from [here](https://code.visualstudio.com/#alt-downloads)
3. Extract it to `D:\Apps\VSCodePortable\App\VSCode`
4. Done, always start Visual Studio Code by using `VSCodePortable.exe`

### Setting-up development environment

Required to be able to recognize your (portable) development environments. Git, MinGW, Python, Java, Node.js, and Go are supported by default.

1. Open `VSCodePortable.exe` at least once
2. Navigate to `D:\Apps\VSCodePortable`
3. Open `VSCodePortable.ini` by using any text editor
4. Look out for `[Environment]` section and change the `GIT`/`MINGW`/`PYTHON`/`JAVA`/`NODEJS`/`GOLANG` value to real path where your development environment exist (please don't point to `bin` folder directly, just the root folder). If the folder/path doesn't exist, it will simply be ignored
5. Done, if you change it to the right path, Visual Studio Code will now be able to recognize your (portable) development environment
6. If you are still unsure, check it by running the development environment executable (e.g. `gcc --version`, `python --version`) inside Visual Studio Code terminal

### Adding unsupported development environment

1. Open `VSCodePortable.exe` at least once
2. Navigate to `D:\Apps\VSCodePortable`
3. Open `VSCodePortable.ini` by using any text editor
4. Look out for the `[Environment]` section and change `PATH` value
5. To append original system `PATH`, use something like `%PATH%;<path_to_your_de>`. You can also use `__clean__` to emulate `PATH` on clean Windows install
6. (Optional) if the development environment checks for specific environment variable (e.g. `XXX_HOME`, `XXXPATH`), navigate to `D:\Apps\VSCodePortable\App\AppInfo\Launcher` and open `VSCodePortable.ini` file. Add new `[Environment]` section (if not exist) and write the needed environment variable (e.g. `XXX_HOME=D:\Apps\VSCodePortable\App\XXX`) under that section
7. To check if your environment variable is recognized, type `echo %PATH%` (Command Prompt) or `echo $PATH` (Bash) or `$env:PATH` (PowerShell) inside Visual Studio Code terminal. Replace `PATH` with other variable name if needed

**Note:** There are 2 different `VSCodePortable.ini` files!

### Supported environment variables

Assuming that you installed VSCodePortable on `D:\Apps\VSCodePortable` (where `VSCodePortable.exe` exist), here is some useful environment variable paths you can use:

* Only read by `VSCodePortable.exe`:
* `PAL:DataDir` : `D:\Apps\VSCodePortable\Data`
* `PAL:AppDir` : `D:\Apps\VSCodePortable\App`
* `PAL:LauncherDir` : `D:\Apps\VSCodePortable`
* `PAL:LauncherPath` : `D:\Apps\VSCodePortable\VSCodePortable.exe`
* `PAL:LauncherFile` : `VSCodePortable.exe`
* `PAL:PortableAppsDir` : `D:\Apps`
* `PAL:CommonFilesDir` : `D:\Apps\CommonFiles`
* More from [here](https://portableapps.com/manuals/PortableApps.comLauncher/ref/launcher.ini/environment.html)

* Read by `Code.exe` and other processes:
* `UserProfile` : `C:\User\<your_username>`
* `AppData` : `C:\User\<your_username>\AppData\Roaming`
* `LocalAppData` : `C:\User\<your_username>\AppData\Local`
* `ProgramData` : `C:\ProgramData`
* `SystemRoot` : `C:\Windows`
* More from [here](https://ss64.com/nt/syntax-variables.html)

**Note:** Some of the environment variables listed here are made by me, so they will not appear on the site.

# Tips

### Lazy to update your development environment?

Some people (including me) are lazy to download new version of development environment everytime a new update was released. Luckily there is [MSYS2](https://www.msys2.org/) that will do all these updates for you by just inputting a single command (`pacman -Syuu`), and it is portable too! Assuming that you have 64 bit OS, you can download it (`.tar` format) from SourceForge [here](https://sourceforge.net/projects/msys2/files/Base/x86_64/).

1. Extract the downloaded MSYS2 to a short path, for example: `C:\MSYS64`
2. Run `msys2_shell.bat` inside the folder (`C:\MSYS64` is the root folder, so it should be `C:\MSYS64\msys2_shell.bat`)
3. Restart MSYS:
* Close MSYS2 by clicking Windows close button (don't type `exit`!)
* Run `msys2_shell.bat` again
4. Inside MSYS2 shell, type `pacman -Syuu` and enter
5. Repeat step 3-4 until all packages are up to date (MSYS2 will say `there is nothing to do`)
6. Install the packages you want. For example:
* MinGW (64 bit): `pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb`
* Python (64 bit): `pacman -S mingw-w64-x86_64-python3 mingw-w64-x86_64-python3-pip`
7. Change both `MINGW` and `PYTHON` values inside `VSCodePortable.ini` to `C:\MSYS64\mingw64`
8. Start `VSCodePortable.exe`, both of them will now be detected if the paths are correct

**Note:** MSYS2 packages may have different folder structures compared to native packages!

# License

* VSCodePortable under the [GPL v2.0 license](https://github.com/AndhikaWB/VSCodePortable/blob/master/LICENSE)
* PortableApps.com Launcher under the [GPL v2.0 license](https://github.com/AndhikaWB/VSCodePortable/blob/master/LICENSE)
* Visual Studio Code under this [license](https://code.visualstudio.com/license)
Binary file added VSCodePortable/App/AppInfo/AppIcon.ico
Binary file not shown.
Binary file added VSCodePortable/App/AppInfo/AppIcon_128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added VSCodePortable/App/AppInfo/AppIcon_16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added VSCodePortable/App/AppInfo/AppIcon_32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added VSCodePortable/App/AppInfo/AppIcon_75.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions VSCodePortable/App/AppInfo/AppInfo.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[Format]
Type=PortableApps.comFormat
Version=3.5

[Details]
Name=Visual Studio Code Portable
AppID=VSCodePortable
Publisher=Microsoft Corporation & Andhika Wibawa
Homepage=https://code.visualstudio.com
Category=Development
Description=Visual Studio Code is a code editor for building and debugging applications
Language=Multilingual

[License]
Shareable=false
OpenSource=false
Freeware=true
CommercialUse=true
EULAVersion=1

[Version]
PackageVersion=1.0.0.15
DisplayVersion=1.0.0 Dev Test 15

;[Dependencies]
;UsesDotNetVersion=4.5.2

[Control]
Icons=1
Start=VSCodePortable.exe
13 changes: 13 additions & 0 deletions VSCodePortable/App/AppInfo/Installer.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[CheckRunning]
CloseEXE=Code.exe

[DownloadFiles]
DownloadURL=https://go.microsoft.com/fwlink/?Linkid=850641
DownloadName=Visual Studio Code x64 (Latest)
DownloadFilename=VSCode-win32-x64-latest.zip
AdditionalInstallSize=2000000
AdvancedExtract1To=App\VSCode
AdvancedExtract1Filter=**

[DirectoriesToPreserve]
PreserveDirectory1=App\VSCode\data
221 changes: 221 additions & 0 deletions VSCodePortable/App/AppInfo/Launcher/Custom.nsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
${SegmentFile}

Var AppDir
Var DataDir
Var DefaultDataDir
Var VSCodeDataDir

Var CmdPath
Var BasePath
Var ExtraPath

Var GitDir
Var MinGWDir
Var PythonDir
Var JavaDir
Var NodeJSDir
Var GolangDir

${SegmentInit}
; Set internal user variables
StrCpy "$AppDir" "$EXEDIR\App"
StrCpy "$DataDir" "$EXEDIR\Data"
StrCpy "$VSCodeDataDir" "$EXEDIR\App\VSCode\data"
StrCpy "$DefaultDataDir" "$EXEDIR\App\FirstRun"
ExpandEnvStrings "$CmdPath" "%COMSPEC%"

; Copy "VSCodePortable.ini" file
${IfNot} ${FileExists} "$EXEDIR\$AppID.ini"
CopyFiles /Silent "$DefaultDataDir\$AppID.ini" "$EXEDIR\$AppID.ini"
${EndIf}
!macroend

${SegmentPre}
; Set custom environment variables
${SetEnvironmentVariablesPath} "PAL:LauncherDir" "$EXEDIR"
${SetEnvironmentVariablesPath} "PAL:LauncherPath" "$EXEPATH"
${SetEnvironmentVariablesPath} "PAL:LauncherFile" "$EXEFILE"
${SetEnvironmentVariablesPath} "PAL:PortableAppsDir" "$PortableAppsDirectory"
${SetEnvironmentVariablesPath} "PAL:CommonFilesDir" "$PortableAppsDirectory\CommonFiles"
!macroend

${SegmentPreExec}
; Read "PATH" environment variable
${ReadUserConfig} "$BasePath" "PATH"
${If} "$BasePath" == ""
ReadEnvStr "$BasePath" "PATH"
${ElseIf} "$BasePath" == "__clean__"
ReadEnvStr "$BasePath" "$WINDIR\System32;$WINDIR;$WINDIR\System32\Wbem;$WINDIR\System32\WindowsPowerShell\v1.0\"
${EndIf}
ExpandEnvStrings "$BasePath" "$BasePath"

; Supported development environments
; Please be aware when using MSYS2 packages
; They may have unsupported folder structures

${ReadUserConfig} "$GitDir" "GIT"
ExpandEnvStrings "$GitDir" "$GitDir"
${If} ${FileExists} "$GitDir\cmd\git.exe"
${If} ${FileExists} "$GitDir\post-install.bat"
nsExec::Exec "$\"$CmdPath$\" /C $\"$\"$GitDir\post-install.bat$\"$\""
${EndIf}
StrCpy "$ExtraPath" "$GitDir\cmd;$GitDir\usr\bin"
${EndIf}

${ReadUserConfig} "$MinGWDir" "MINGW"
ExpandEnvStrings "$MinGWDir" "$MinGWDir"
${If} ${FileExists} "$MinGWDir\bin\gcc.exe"
StrCpy "$ExtraPath" "$ExtraPath;$MinGWDir\bin"
${EndIf}

; For portability reason, do not install Python module per user
; Use "Global Module Installation" instead when using Python extension
; This is already set by default, go to settings to revert it

${ReadUserConfig} "$PythonDir" "PYTHON"
ExpandEnvStrings "$PythonDir" "$PythonDir"
${If} ${FileExists} "$PythonDir\python.exe"
nsExec::ExecToStack "$\"$PythonDir\python.exe$\" -m site --user-site"
Pop $R1
${If} $R1 == 0
Pop $R2
${GetParent} $R2 $R2
StrCpy "$ExtraPath" "$ExtraPath;$PythonDir;$PythonDir\scripts;$R2\scripts"
${Else}
StrCpy "$ExtraPath" "$ExtraPath;$PythonDir;$PythonDir\scripts"
${EndIf}
ExpandEnvStrings $R3 "%PYTHONPATH%"
${If} $R3 == ""
${SetEnvironmentVariablesPath} "PYTHONPATH" "$PythonDir\lib;$PythonDir\dlls"
${Else}
${SetEnvironmentVariablesPath} "PYTHONPATH" "$PythonDir\lib;$PythonDir\dlls;$R3"
${EndIf}
${EndIf}

${ReadUserConfig} "$JavaDir" "JAVA"
ExpandEnvStrings "$JavaDir" "$JavaDir"
${If} ${FileExists} "$JavaDir\bin\java.exe"
StrCpy "$ExtraPath" "$ExtraPath;$JavaDir\bin"
${SetEnvironmentVariablesPath} "JAVA_HOME" "$JavaDir"
${EndIf}

; For portability reason, "prefix" and "cache" path must be changed beforehand
; You can either edit "npmrc" file directly or use "npm config set" command
; Why not automate it? Many people use non-portable Node.js already

${ReadUserConfig} "$NodeJSDir" "NODEJS"
ExpandEnvStrings "$NodeJSDir" "$NodeJSDir"
${If} ${FileExists} "$NodeJSDir\node.exe"
nsExec::ExecToStack "$\"$CmdPath$\" /C $\"$\"$NodeJSDir\npm.cmd$\"$\" config get prefix"
Pop $R1
${If} $R1 == 0
Pop $R2
StrCpy "$ExtraPath" "$ExtraPath;$NodeJSDir;$R2"
${Else}
StrCpy "$ExtraPath" "$ExtraPath;$NodeJSDir"
${EndIf}
${EndIf}

${ReadUserConfig} "$GolangDir" "GOLANG"
ExpandEnvStrings "$GolangDir" "$GolangDir"
${If} ${FileExists} "$GolangDir\bin\go.exe"
StrCpy "$ExtraPath" "$ExtraPath;$GolangDir\bin"
${SetEnvironmentVariablesPath} "GOPATH" "$GolangDir"
${EndIf}

; Prepend all valid environments onto the "PATH" environment variable
; Modified "PATH" will only be read by VSCode and its spawned processes
; "PATH" longer than 8196 bytes will be reverted to default

StrLen $R1 "$ExtraPath_$BasePath_"
IntOp $R1 $R1 * ${NSIS_CHAR_SIZE}
${If} $R1 < ${NSIS_MAX_STRLEN}
${SetEnvironmentVariablesPath} "PATH" "$ExtraPath;$BasePath"
${Else}
MessageBox MB_OK|MB_ICONEXCLAMATION "The modified $\"PATH$\" environment variable is too long, reverting to default as workaround."
${EndIf}

; Copy "user-data" folder
CreateDirectory "$VSCodeDataDir"
${IfNot} ${FileExists} "$VSCodeDataDir\user-data\*.*"
CopyFiles /Silent "$DefaultDataDir\VSCode\user-data\*.*" "$VSCodeDataDir\user-data"
${EndIf}

; Install VSIX files to "extensions" folder
${IfNot} ${FileExists} "$VSCodeDataDir\extensions\*.*"
FindFirst $R1 $R2 "$DefaultDataDir\VSCode\extensions\*.vsix"
CheckFile:
${If} $R2 != ""
MessageBox MB_YESNO|MB_ICONQUESTION "Do you want to install $\"$R2$\"? It may take a while, please be patient." IDNO +2
ExecWait "$\"$CmdPath$\" /C $\"$\"$AppDir\VSCode\bin\code.cmd$\" --install-extension $\"$DefaultDataDir\VSCode\extensions\$R2$\"$\""
FindNext $R1 $R2
Goto CheckFile
${EndIf}
FindClose $R1
${EndIf}

; Create shortcuts to "user-data" folder
CreateDirectory "$DataDir"
Delete "$DataDir\user-data.lnk"
CreateShortCut "$DataDir\user-data.lnk" "$VSCodeDataDir\user-data"

; Create shortcuts to "extensions" folder
Delete "$DataDir\extensions.lnk"
CreateShortCut "$DataDir\extensions.lnk" "$VSCodeDataDir\extensions"
!macroend

/*
${OverrideExecute}
Exec "$ExecString"
Sleep 5000
; Overwrite values written by VSCode at launch
WriteRegStr HKCR "vscode\shell\open\command" "" "$\"$EXEPATH$\" --open-url -- $\"%1$\""
WriteRegStr HKCU "Software\Classes\vscode\shell\open\command" "" "$\"$EXEPATH$\" --open-url -- $\"%1$\""
CheckProcess:
${If} ${ProcessExists} "Code.exe"
${GetProcessPath} "Code.exe" $R1
${If} $R1 == "$AppDir\VSCode\Code.exe"
Sleep 1000
Goto CheckProcess
${EndIf}
${EndIf}
!macroend
*/

${SegmentPostPrimary}
; PAF installer related leftovers
Delete "$AppDir\AppInfo\pac_installer_log.ini"
RMDir /r "$DataDir\PortableApps.comInstaller"
RMDir "$EXEDIR\Other\Source"

; Live Share related leftovers
DeleteRegKey HKCR "vsls"
DeleteRegKey HKCR "code.launcher.handler"
DeleteRegKey HKCU "Software\Classes\vsls"
DeleteRegKey HKCU "Software\Classes\code.launcher.handler"
DeleteRegKey HKCU "Software\code.launcher"
DeleteRegValue HKCU "Software\RegisteredApplications" "code.launcher"

; C/C++ related leftovers
RMDir /r "$LOCALAPPDATA\Microsoft\vscode-cpptools"

; Python related leftovers
RMDir /r "$PROFILE\.pylint.d"
RMDir /r "$LOCALAPPDATA\Jedi"
RMDir "$LOCALAPPDATA\pip\cache"
RMDir "$LOCALAPPDATA\pip"

; Java related leftovers
Delete "$PROFILE\.tooling\gradle\versions.json"
RMDir "$PROFILE\.tooling\gradle"
RMDir "$PROFILE\.tooling"

; Node.js related leftovers
Delete "$PROFILE\.config\configstore\update-notifier-npm.json"
RMDir "$PROFILE\.config\configstore"
RMDir "$PROFILE\.config"
RMDir "$APPDATA\npm-cache"
RMDir "$APPDATA\npm"
!macroend
Loading

0 comments on commit 0d51a1b

Please sign in to comment.