diff --git a/CHANGELOG.md b/CHANGELOG.md
index ffc7986708538793fca6adfbfc4f0387d6aaf31a..e6df913be88a5845fa81b3fe1639ee465d5678a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@
 * Added a `:bsymb` command to load ProB's custom bsymb.sty LaTeX definitions on demand. After this command is executed, bsymb commands can be used in LaTeX formulas in Markdown cells.
 * Added support for Java 11.
 * Updated ProB 2 to version 3.2.12.
+* Fixed installation problems under Windows (paths in the kernel metadata are now escaped correctly).
 * Fixed confusing handling of trailing spaces in commands.
 * Fixed `:show` not displaying animation images correctly for machines outside of the kernel's working directory.
 * Fixed `:trace` not showing the parameters and return values of executed transitions.
diff --git a/build.gradle b/build.gradle
index 098dc85edbc6067266c6606945aa738569d3de09..059a6322b471100072a5f029acfa94f7ea284c4b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -33,6 +33,7 @@ configurations.all {
 }
 
 dependencies {
+	implementation(group: "com.google.code.gson", name: "gson", version: "2.8.6")
 	implementation(group: "com.google.guava", name: "guava", version: "28.2-jre")
 	implementation(group: "de.hhu.stups", name: "de.prob2.kernel", version: "4.0.0-SNAPSHOT")
 	implementation(group: "io.github.spencerpark", name: "jupyter-jvm-basekernel", version: "2.3.0")
diff --git a/src/main/java/de/prob2/jupyter/Main.java b/src/main/java/de/prob2/jupyter/Main.java
index 084afe112be451ccc672fba3ec24ce90e5115cd9..de37197afd28f0fbe3087f000e58f8ab03763df1 100644
--- a/src/main/java/de/prob2/jupyter/Main.java
+++ b/src/main/java/de/prob2/jupyter/Main.java
@@ -1,10 +1,9 @@
 package de.prob2.jupyter;
 
-import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.UncheckedIOException;
+import java.io.Writer;
 import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
@@ -14,10 +13,13 @@ import java.nio.file.StandardCopyOption;
 import java.security.CodeSource;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.stream.Collectors;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.stream.Stream;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.annotations.SerializedName;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
@@ -28,6 +30,16 @@ import io.github.spencerpark.jupyter.kernel.KernelConnectionProperties;
 import org.jetbrains.annotations.Nullable;
 
 public final class Main {
+	private static final class KernelJsonData {
+		List<String> argv;
+		@SerializedName("display_name") String displayName;
+		String language;
+		
+		KernelJsonData() {
+			super();
+		}
+	}
+	
 	private Main() {
 		super();
 		
@@ -98,24 +110,35 @@ public final class Main {
 			}
 		});
 		
+		final List<String> kernelJsonArgv = new ArrayList<>();
+		kernelJsonArgv.add("java");
+		
 		final String probHome = System.getProperty("prob.home");
-		final String probHomeDef;
 		if (probHome != null) {
 			System.out.println("prob.home is set, adding a corresponding prob.home defintion to kernel.json: " + probHome);
-			probHomeDef = String.format("\n\t\t\"-Dprob.home=%s\",", probHome);
+			kernelJsonArgv.add("-Dprob.home=" + probHome);
 		} else {
 			System.out.println("prob.home is not set, not adding a prob.home definition to kernel.json");
-			probHomeDef = "";
 		}
 		
+		kernelJsonArgv.add("-jar");
+		kernelJsonArgv.add(jarPath.toString());
+		kernelJsonArgv.add("run");
+		kernelJsonArgv.add("{connection_file}");
+		
+		final Main.KernelJsonData kernelJsonData = new Main.KernelJsonData();
+		kernelJsonData.argv = kernelJsonArgv;
+		kernelJsonData.displayName = "ProB 2";
+		kernelJsonData.language = "prob";
+		
+		final Gson gson = new GsonBuilder()
+			.setPrettyPrinting()
+			.serializeNulls()
+			.create();
+		
 		System.out.println("Creating kernel.json");
-		try (
-			final InputStream is = Main.class.getResourceAsStream("kernelspecfiles/kernel.json.template");
-			final InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
-			final BufferedReader br = new BufferedReader(isr);
-		) {
-			final String kernelJsonText = String.format(br.lines().collect(Collectors.joining("\n")), probHomeDef, jarPath);
-			Files.write(kernelSpecDir.resolve("kernel.json"), Arrays.asList(kernelJsonText.split("\n")));
+		try (final Writer writer = Files.newBufferedWriter(kernelSpecDir.resolve("kernel.json"))) {
+			gson.toJson(kernelJsonData, writer);
 		} catch (final IOException e) {
 			System.err.println("Failed to create kernel.json");
 			e.printStackTrace();
diff --git a/src/main/resources/de/prob2/jupyter/kernelspecfiles/kernel.json.template b/src/main/resources/de/prob2/jupyter/kernelspecfiles/kernel.json.template
deleted file mode 100644
index 6af4f8e3cce8eff4648ea063dcc7221aea281ce9..0000000000000000000000000000000000000000
--- a/src/main/resources/de/prob2/jupyter/kernelspecfiles/kernel.json.template
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-	"argv": [
-		"java",%s
-		"-jar",
-		"%s",
-		"run",
-		"{connection_file}"
-	],
-	"display_name": "ProB 2",
-	"language": "prob"
-}