Created a Custom Obsidian Vault Launcher for a Registered `.vault` Extension (Windows)

Custom Obsidian “.vault” Extension

Recently I created a way to include a .vault extension for my obsidian vault directory to launch the vault like a “project” (i.e. code workspace *.code-workspace, RStudio Project *.Rproj, etc.).

Since I am on Windows my solution would only work for Windows, but could easily (ish) be ported for other OS’s.

Demo

2023-01-14_Obsidian_Vault_Launcher

Overview

On Windows, you can associate any custom command with a file extension. To do this you must follow the steps below:

  1. Update the PATHEXT environment variable.
  2. Associate the file extension to a “FileType”.
  3. Specify the command to run when that file type is executed.

Implementation

Update PATHEXT Environment Variable

To update the PATHEXT environment variable I simply executed the command:

SETX PATHEXT %PATHEXT%;.VAULT

Associate the File Extension and Register it to a Command

To create the file association for the .vault extension I decided to call the associated file type ObsidianVault.File which follows standards:

ASSOC .vault=ObsidianVault.File

Lastly, to bind the file type to a command (in my case the command should launch the obsidian vault in the obsidian application), I ran the code below:

FTYPE ObsidianVault.File=pwsh.exe -NoProfile -w Hidden "%USERPROFILE%\bin\Open-ObsidianVault.ps1" -Vault "%1" %*

Script

I decided to utilize a powershell script in my ~/bin directory, but could have performed the same thing by putting the command inline also.

The script relies on the Obsidian URI and is below:

<# 

.DESCRIPTION 
    Launches an Obsidian Vault 

.PARAMETER Vault
    Name OR Path of the Vault to Launch.

.EXAMPLE
    Open-ObsidianVault -Vault "C:\Users\Jimmy\Documents\Obsidian"
#> 
Param(
    [Parameter(Mandatory=$true)]
    [string]$Vault
)

If ($Vault -like "*:\*") {
    $Vault = Split-Path $Vault -Leaf 
}

$Vault = (($Vault.Replace(" ", "%20")).Replace("\", "/")).Replace(".vault", "")

$URI = "obsidian://vault/$Vault"

Start-Process $URI -Wait

This script takes the vault name from the .vault file’s path and adjusts it for URL Encoding and runs the URI as a new process.

Extra Credit - Add DefaultIcon

The final step I took was to assign the .vault extension’s default icon so that it wouldn’t default to the powershell executable’s icon.

To do this I added a new DefaultIcon Registry sub-key under the ObsidianVault.File file association at the path HKEY_CLASSES_ROOT\ObsidianVault.File\DefaultIcon with the value referencing the icon from the default obsidian application executable: %LOCALAPPDATA%\Obsidian\Obsidian.exe,0:

# Create new sub-key for DefaultIcon
Get-Item -Path 'HKCR:\ObsidianVault.File' | New-Item -Name 'DefaultIcon' -Force

# Add default value of type REG_SZ for the icon's source location
New-ItemProperty -Path 'HKCR:\ObsidianVault.File\DefaultIcon' -Name '(Default)' -Value "%LOCALAPPDATA%\Obsidian\Obsidian.exe,0" -PropertyType REG_SZ -Force