windows-development-sandbox 1.23.2 → 1.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.example.json +5 -3
- package/dist/app/features/data/data.def.d.ts +4 -4
- package/dist/app/features/data/data.run.d.ts +1 -1
- package/dist/app/features/defs.d.ts +161 -6
- package/dist/app/features/defs.js +7 -0
- package/dist/app/features/projects/projects.def.d.ts +1 -1
- package/dist/app/features/projects/projects.run.d.ts +1 -1
- package/dist/app/features/unreal/index.d.ts +2 -0
- package/dist/app/features/unreal/index.js +3 -0
- package/dist/app/features/unreal/unreal.def.d.ts +236 -0
- package/dist/app/features/unreal/unreal.def.js +379 -0
- package/dist/app/features/unreal/unreal.run.d.ts +96 -0
- package/dist/app/features/unreal/unreal.run.js +217 -0
- package/dist/app/registry.js +5 -0
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-7YPEDAJD.js → chunk-3GAXLATK.js} +58 -5
- package/dist/bin/{chunk-USTRSHIE.js → chunk-F4PVBN23.js} +2615 -1515
- package/dist/bin/{chunk-QFSJX2KW.js → chunk-G3TG4ZT7.js} +1 -1
- package/dist/bin/claude-host.js +2 -2
- package/dist/bin/claude-sbx.js +2 -2
- package/dist/bin/codex-sbx.js +2 -2
- package/dist/bin/gemini-sbx.js +2 -2
- package/dist/bin/sandbox.js +2 -2
- package/dist/bin/sbx-hide.js +2 -2
- package/dist/bin/sbx-show.js +2 -2
- package/dist/cli/commands/launch/launch.js +5 -2
- package/dist/cli/commands/registry.js +3 -0
- package/dist/cli/manifest.d.ts +18 -0
- package/dist/cli/manifest.js +26 -0
- package/dist/cli/menu/coverage-exempt.js +1 -0
- package/dist/cli/menu/pages/sandbox-page.d.ts +3 -0
- package/dist/cli/menu/pages/sandbox-page.js +34 -4
- package/dist/cli/menu/views.js +2 -0
- package/dist/core/config/defaults.js +18 -5
- package/dist/core/detect/toolchains.js +0 -6
- package/dist/core/schema/config.d.ts +10 -9
- package/dist/core/schema/pc-installs.d.ts +3 -1
- package/dist/core/schema/pc-installs.js +10 -1
- package/dist/core/schema/toolchains.d.ts +1 -2
- package/dist/core/schema/toolchains.js +4 -7
- package/dist/guest/accounts/kinds/epic.js +18 -13
- package/dist/guest/agents/agent-files.d.ts +11 -7
- package/dist/guest/agents/agent-files.js +37 -11
- package/dist/guest/agents/local-state.d.ts +2 -1
- package/dist/guest/agents/local-state.js +2 -1
- package/dist/guest/apps/after-install.d.ts +1 -1
- package/dist/guest/apps/after-install.js +6 -1
- package/dist/guest/apps/app-installer.d.ts +1 -0
- package/dist/guest/apps/app-installer.js +13 -3
- package/dist/guest/apps/comet-unpack.js +3 -2
- package/dist/guest/apps/resolvers-gamedev.js +55 -1
- package/dist/guest/boot/boot-console.d.ts +28 -0
- package/dist/guest/boot/boot-console.js +98 -0
- package/dist/guest/boot/boot.d.ts +8 -1
- package/dist/guest/boot/boot.js +80 -43
- package/dist/guest/boot/graph.d.ts +9 -5
- package/dist/guest/boot/graph.js +8 -2
- package/dist/guest/boot/guide.js +24 -0
- package/dist/guest/boot/progress-view.d.ts +116 -0
- package/dist/guest/boot/progress-view.js +456 -0
- package/dist/guest/boot/runner.d.ts +20 -10
- package/dist/guest/boot/runner.js +39 -47
- package/dist/guest/daemon/daemon.js +3 -0
- package/dist/guest/runtime/log-line.d.ts +7 -0
- package/dist/guest/runtime/log-line.js +18 -0
- package/dist/guest/runtime/log.d.ts +17 -4
- package/dist/guest/runtime/log.js +40 -17
- package/dist/guest/runtime/process.d.ts +9 -0
- package/dist/guest/runtime/process.js +69 -8
- package/dist/guest/setup/addon-mcp.d.ts +7 -0
- package/dist/guest/setup/addon-mcp.js +19 -4
- package/dist/guest/setup/browser-gpu.js +14 -11
- package/dist/guest/setup/environment.js +9 -4
- package/dist/guest/setup/headroom.js +4 -0
- package/dist/guest/setup/hooks.d.ts +2 -0
- package/dist/guest/setup/hooks.js +4 -0
- package/dist/guest/setup/path-plan.d.ts +12 -0
- package/dist/guest/setup/path-plan.js +18 -0
- package/dist/guest/toolchains/engines/epic-launcher.d.ts +26 -0
- package/dist/guest/toolchains/engines/epic-launcher.js +127 -0
- package/dist/guest/toolchains/engines/unreal-engines.d.ts +21 -1
- package/dist/guest/toolchains/engines/unreal-engines.js +163 -3
- package/dist/guest/toolchains/engines/unreal-status.d.ts +13 -0
- package/dist/guest/toolchains/engines/unreal-status.js +41 -0
- package/dist/guest/toolchains/native/debuggers.d.ts +6 -0
- package/dist/guest/toolchains/native/debuggers.js +57 -0
- package/dist/guest/toolchains/native/mesa.js +15 -8
- package/dist/guest/toolchains/native/rust-extras.d.ts +7 -0
- package/dist/guest/toolchains/native/rust-extras.js +23 -1
- package/dist/guest/toolchains/native/unreal.d.ts +2 -2
- package/dist/guest/toolchains/native/unreal.js +96 -20
- package/dist/guest/toolchains/native/visual-studio.d.ts +14 -14
- package/dist/guest/toolchains/native/visual-studio.js +145 -174
- package/dist/guest/toolchains/native/vs-persist.d.ts +189 -0
- package/dist/guest/toolchains/native/vs-persist.js +256 -0
- package/dist/guest/toolchains/native/vs-request.d.ts +6 -26
- package/dist/guest/toolchains/native/vs-request.js +16 -50
- package/dist/guest/toolchains/plan.js +23 -15
- package/dist/guest/toolchains/tools/vscode-profile.js +2 -0
- package/dist/host/accounts/kinds/epic.js +11 -5
- package/dist/host/accounts/source.d.ts +2 -0
- package/dist/host/accounts/source.js +1 -0
- package/dist/host/migrate/migrations/drop-vs-install-files.d.ts +5 -0
- package/dist/host/migrate/migrations/drop-vs-install-files.js +34 -0
- package/dist/host/migrate/registry.js +7 -1
- package/dist/host/pc-installs/discover.d.ts +2 -0
- package/dist/host/pc-installs/discover.js +25 -5
- package/dist/host/pc-installs/epic.d.ts +3 -0
- package/dist/host/pc-installs/epic.js +33 -2
- package/dist/host/pc-installs/source.d.ts +1 -1
- package/dist/host/pc-installs/unreal-vault.d.ts +11 -0
- package/dist/host/pc-installs/unreal-vault.js +78 -0
- package/dist/host/pc-installs/unreal.d.ts +36 -0
- package/dist/host/pc-installs/unreal.js +145 -2
- package/dist/host/profile/claude-profile.d.ts +8 -0
- package/dist/host/profile/claude-profile.js +43 -4
- package/dist/host/profile/index.d.ts +1 -1
- package/dist/host/profile/index.js +1 -1
- package/dist/runtime/agent.js +148 -33
- package/dist/runtime/daemon.js +3146 -1546
- package/dist/runtime/db.js +148 -33
- package/dist/runtime/main.js +3982 -2049
- package/dist/runtime/netproxy.js +84 -13
- package/dist/runtime/tool.js +125 -31
- package/dist/runtime/view.js +85 -14
- package/dist/selftest/agent-paths.test.js +18 -1
- package/dist/selftest/agent-settings.test.js +36 -5
- package/dist/selftest/agents-web.test.js +12 -0
- package/dist/selftest/boot-console.test.d.ts +2 -0
- package/dist/selftest/boot-console.test.js +291 -0
- package/dist/selftest/boot-runner.test.js +10 -12
- package/dist/selftest/engines.test.js +602 -3
- package/dist/selftest/guest-boot.test.js +7 -1
- package/dist/selftest/heavy-load.test.js +3 -1
- package/dist/selftest/hostile-input.test.js +11 -1
- package/dist/selftest/index.js +4 -0
- package/dist/selftest/layout.test.js +4 -0
- package/dist/selftest/menu-screens.js +3 -1
- package/dist/selftest/migrate.test.js +21 -0
- package/dist/selftest/mixamo.test.d.ts +2 -0
- package/dist/selftest/mixamo.test.js +60 -0
- package/dist/selftest/persisted-installs.test.js +169 -33
- package/dist/selftest/secrets.test.js +36 -1
- package/dist/selftest/support/engine-golden.js +5 -0
- package/dist/selftest/support/fixtures.d.ts +4 -3
- package/dist/selftest/support/unreal-sample.d.ts +2 -0
- package/dist/selftest/support/unreal-sample.js +83 -0
- package/dist/selftest/toolchains.test.js +32 -2
- package/dist/shared/accounts/index.d.ts +1 -1
- package/dist/shared/accounts/index.js +1 -1
- package/dist/shared/accounts/kinds/epic.d.ts +6 -1
- package/dist/shared/accounts/kinds/epic.js +11 -1
- package/dist/shared/apps/associations.d.ts +7 -0
- package/dist/shared/apps/associations.js +26 -0
- package/dist/shared/apps/catalogue-agents-web.d.ts +4 -1
- package/dist/shared/apps/catalogue-agents-web.js +5 -2
- package/dist/shared/apps/catalogue-gamedev.js +71 -1
- package/dist/shared/apps/index.d.ts +2 -0
- package/dist/shared/apps/index.js +2 -0
- package/dist/shared/apps/preview.d.ts +2 -0
- package/dist/shared/apps/preview.js +10 -0
- package/dist/shared/browser-policy.d.ts +14 -0
- package/dist/shared/browser-policy.js +22 -0
- package/dist/shared/channel/schema.d.ts +3 -6
- package/dist/shared/io/index.d.ts +1 -0
- package/dist/shared/io/index.js +1 -0
- package/dist/shared/io/rotate-log.d.ts +2 -0
- package/dist/shared/io/rotate-log.js +16 -0
- package/dist/shared/memory/policy.d.ts +5 -0
- package/dist/shared/memory/policy.js +7 -0
- package/dist/shared/paths/pc-installs.d.ts +13 -2
- package/dist/shared/paths/pc-installs.js +1 -0
- package/dist/shared/pty/terminal.js +2 -1
- package/dist/shared/readiness.d.ts +0 -1
- package/dist/shared/readiness.js +0 -1
- package/dist/shared/signer.d.ts +4 -0
- package/dist/shared/signer.js +2 -0
- package/dist/shared/unreal/engines.d.ts +161 -0
- package/dist/shared/unreal/engines.js +308 -0
- package/dist/shared/unreal/guide.d.ts +19 -0
- package/dist/shared/unreal/guide.js +105 -0
- package/dist/shared/unreal/index.d.ts +7 -0
- package/dist/shared/unreal/index.js +8 -0
- package/dist/shared/unreal/launcher-files.d.ts +88 -0
- package/dist/shared/unreal/launcher-files.js +292 -0
- package/dist/shared/unreal/mixamo.d.ts +5 -0
- package/dist/shared/unreal/mixamo.js +16 -0
- package/dist/shared/unreal/room.d.ts +17 -0
- package/dist/shared/unreal/room.js +34 -0
- package/dist/shared/unreal/status.d.ts +54 -0
- package/dist/shared/unreal/status.js +57 -0
- package/dist/shared/unreal/vault.d.ts +21 -0
- package/dist/shared/unreal/vault.js +67 -0
- package/dist/shared/unreal/vs-check.d.ts +39 -0
- package/dist/shared/unreal/vs-check.js +79 -0
- package/dist/sync/watcher.js +5 -1
- package/dist/web/index.html +1 -1
- package/dist/web/{main-CCILLX2M.js → main-FNE6XEHA.js} +84 -84
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/package.json +1 -1
- package/sandbox/csharp/VsSetup.cs +210 -0
- package/sandbox/scripts/get-vs-setup.ps1 +93 -0
- package/sandbox/scripts/restore-visual-studio.ps1 +78 -0
- package/sandbox/scripts/save-visual-studio.ps1 +106 -0
- package/sandbox/scripts/set-registry-values.ps1 +35 -0
- package/schemas/config.schema.json +38 -9
- package/schemas/sandbox-config.schema.json +11 -8
- package/dist/guest/toolchains/native/autosdk.d.ts +0 -3
- package/dist/guest/toolchains/native/autosdk.js +0 -50
|
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
|
|
|
8
8
|
[assembly: AssemblyCompany("windows-development-sandbox (open source)")]
|
|
9
9
|
[assembly: AssemblyProduct("Windows Development Sandbox")]
|
|
10
10
|
[assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
|
|
11
|
-
[assembly: AssemblyVersion("1.
|
|
12
|
-
[assembly: AssemblyFileVersion("1.
|
|
13
|
-
[assembly: AssemblyInformationalVersion("1.
|
|
11
|
+
[assembly: AssemblyVersion("1.25.0.0")]
|
|
12
|
+
[assembly: AssemblyFileVersion("1.25.0.0")]
|
|
13
|
+
[assembly: AssemblyInformationalVersion("1.25.0")]
|
|
14
14
|
[assembly: ComVisible(false)]
|
|
15
15
|
// computecore.dll and computestorage.dll are not KnownDLLs: load them from System32 only, never from the exe's folder.
|
|
16
16
|
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
|
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
|
|
|
8
8
|
[assembly: AssemblyCompany("windows-development-sandbox (open source)")]
|
|
9
9
|
[assembly: AssemblyProduct("Windows Development Sandbox")]
|
|
10
10
|
[assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
|
|
11
|
-
[assembly: AssemblyVersion("1.
|
|
12
|
-
[assembly: AssemblyFileVersion("1.
|
|
13
|
-
[assembly: AssemblyInformationalVersion("1.
|
|
11
|
+
[assembly: AssemblyVersion("1.25.0.0")]
|
|
12
|
+
[assembly: AssemblyFileVersion("1.25.0.0")]
|
|
13
|
+
[assembly: AssemblyInformationalVersion("1.25.0")]
|
|
14
14
|
[assembly: ComVisible(false)]
|
|
@@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
|
|
|
9
9
|
[assembly: AssemblyCompany("windows-development-sandbox (open source)")]
|
|
10
10
|
[assembly: AssemblyProduct("Windows Development Sandbox")]
|
|
11
11
|
[assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
|
|
12
|
-
[assembly: AssemblyVersion("1.
|
|
13
|
-
[assembly: AssemblyFileVersion("1.
|
|
14
|
-
[assembly: AssemblyInformationalVersion("1.
|
|
12
|
+
[assembly: AssemblyVersion("1.25.0.0")]
|
|
13
|
+
[assembly: AssemblyFileVersion("1.25.0.0")]
|
|
14
|
+
[assembly: AssemblyInformationalVersion("1.25.0")]
|
|
15
15
|
[assembly: ComVisible(false)]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "windows-development-sandbox",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.1",
|
|
4
4
|
"description": "A disposable Windows Sandbox for development, with or without an AI agent (Claude Code, Codex, Gemini, opencode, ...): the folder you run it from is the workspace, toolchains and databases for your project install themselves, and nothing else on your PC is reachable.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// The Visual Studio Setup Configuration API as UnrealBuildTool calls it (MicrosoftPlatformSDK: SetupConfiguration,
|
|
2
|
+
// ISetupConfiguration2.EnumAllInstances, ISetupInstance2): every instance with its state, version, product, path and
|
|
3
|
+
// packages. Loaded by scripts\get-vs-setup.ps1 (Add-Type), which adds the file checks and writes the JSON. C# 5.
|
|
4
|
+
using System;
|
|
5
|
+
using System.Collections.Generic;
|
|
6
|
+
using System.Runtime.InteropServices;
|
|
7
|
+
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
|
|
8
|
+
|
|
9
|
+
namespace AgentSandbox
|
|
10
|
+
{
|
|
11
|
+
[ComImport]
|
|
12
|
+
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
|
13
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
14
|
+
public interface ISetupConfiguration
|
|
15
|
+
{
|
|
16
|
+
IEnumSetupInstances EnumInstances();
|
|
17
|
+
ISetupInstance GetInstanceForCurrentProcess();
|
|
18
|
+
ISetupInstance GetInstanceForPath([In, MarshalAs(UnmanagedType.LPWStr)] string path);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
[ComImport]
|
|
22
|
+
[Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
|
|
23
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
24
|
+
public interface ISetupConfiguration2 : ISetupConfiguration
|
|
25
|
+
{
|
|
26
|
+
new IEnumSetupInstances EnumInstances();
|
|
27
|
+
new ISetupInstance GetInstanceForCurrentProcess();
|
|
28
|
+
new ISetupInstance GetInstanceForPath([In, MarshalAs(UnmanagedType.LPWStr)] string path);
|
|
29
|
+
IEnumSetupInstances EnumAllInstances();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
[ComImport]
|
|
33
|
+
[Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
|
|
34
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
35
|
+
public interface IEnumSetupInstances
|
|
36
|
+
{
|
|
37
|
+
void Next(
|
|
38
|
+
[In, MarshalAs(UnmanagedType.U4)] int celt,
|
|
39
|
+
[Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)]
|
|
40
|
+
ISetupInstance[] rgelt,
|
|
41
|
+
[Out, MarshalAs(UnmanagedType.U4)] out int pceltFetched);
|
|
42
|
+
void Skip([In, MarshalAs(UnmanagedType.U4)] int celt);
|
|
43
|
+
void Reset();
|
|
44
|
+
IEnumSetupInstances Clone();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
[ComImport]
|
|
48
|
+
[Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
|
|
49
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
50
|
+
public interface ISetupInstance
|
|
51
|
+
{
|
|
52
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetInstanceId();
|
|
53
|
+
[return: MarshalAs(UnmanagedType.Struct)] FILETIME GetInstallDate();
|
|
54
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetInstallationName();
|
|
55
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetInstallationPath();
|
|
56
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetInstallationVersion();
|
|
57
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetDisplayName([In, MarshalAs(UnmanagedType.U4)] int lcid);
|
|
58
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetDescription([In, MarshalAs(UnmanagedType.U4)] int lcid);
|
|
59
|
+
[return: MarshalAs(UnmanagedType.BStr)] string ResolvePath([In, MarshalAs(UnmanagedType.LPWStr)] string path);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[ComImport]
|
|
63
|
+
[Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
|
|
64
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
65
|
+
public interface ISetupInstance2 : ISetupInstance
|
|
66
|
+
{
|
|
67
|
+
[return: MarshalAs(UnmanagedType.BStr)] new string GetInstanceId();
|
|
68
|
+
[return: MarshalAs(UnmanagedType.Struct)] new FILETIME GetInstallDate();
|
|
69
|
+
[return: MarshalAs(UnmanagedType.BStr)] new string GetInstallationName();
|
|
70
|
+
[return: MarshalAs(UnmanagedType.BStr)] new string GetInstallationPath();
|
|
71
|
+
[return: MarshalAs(UnmanagedType.BStr)] new string GetInstallationVersion();
|
|
72
|
+
[return: MarshalAs(UnmanagedType.BStr)] new string GetDisplayName([In, MarshalAs(UnmanagedType.U4)] int lcid);
|
|
73
|
+
[return: MarshalAs(UnmanagedType.BStr)] new string GetDescription([In, MarshalAs(UnmanagedType.U4)] int lcid);
|
|
74
|
+
[return: MarshalAs(UnmanagedType.BStr)] new string ResolvePath([In, MarshalAs(UnmanagedType.LPWStr)] string path);
|
|
75
|
+
[return: MarshalAs(UnmanagedType.U4)] uint GetState();
|
|
76
|
+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
|
77
|
+
ISetupPackageReference[] GetPackages();
|
|
78
|
+
ISetupPackageReference GetProduct();
|
|
79
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetProductPath();
|
|
80
|
+
[return: MarshalAs(UnmanagedType.IUnknown)] object GetErrors();
|
|
81
|
+
[return: MarshalAs(UnmanagedType.VariantBool)] bool IsLaunchable();
|
|
82
|
+
[return: MarshalAs(UnmanagedType.VariantBool)] bool IsComplete();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
[ComImport]
|
|
86
|
+
[Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
|
|
87
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
88
|
+
public interface ISetupPackageReference
|
|
89
|
+
{
|
|
90
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetId();
|
|
91
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetVersion();
|
|
92
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetChip();
|
|
93
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetLanguage();
|
|
94
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetBranch();
|
|
95
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetType();
|
|
96
|
+
[return: MarshalAs(UnmanagedType.BStr)] string GetUniqueId();
|
|
97
|
+
[return: MarshalAs(UnmanagedType.VariantBool)] bool GetIsExtension();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
[ComImport]
|
|
101
|
+
[Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
|
|
102
|
+
[ClassInterface(ClassInterfaceType.None)]
|
|
103
|
+
public class SetupConfiguration
|
|
104
|
+
{
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/// <summary>One instance as the Setup API reports it.</summary>
|
|
108
|
+
public class SetupInstanceInfo
|
|
109
|
+
{
|
|
110
|
+
public string InstanceId;
|
|
111
|
+
public string InstallationPath;
|
|
112
|
+
public string InstallationVersion;
|
|
113
|
+
public string ProductId;
|
|
114
|
+
public uint State;
|
|
115
|
+
public bool IsComplete;
|
|
116
|
+
public bool IsLaunchable;
|
|
117
|
+
public string[] Packages;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public static class VsSetup
|
|
121
|
+
{
|
|
122
|
+
/// <summary>InstanceState.Local: the instance's files are on this machine (the only ones UnrealBuildTool uses).</summary>
|
|
123
|
+
public const uint StateLocal = 1;
|
|
124
|
+
|
|
125
|
+
/// <summary>Every instance EnumAllInstances lists (complete or not), as UnrealBuildTool enumerates them.</summary>
|
|
126
|
+
public static SetupInstanceInfo[] AllInstances()
|
|
127
|
+
{
|
|
128
|
+
List<SetupInstanceInfo> found = new List<SetupInstanceInfo>();
|
|
129
|
+
ISetupConfiguration2 setup = (ISetupConfiguration2)new SetupConfiguration();
|
|
130
|
+
IEnumSetupInstances instances = null;
|
|
131
|
+
try
|
|
132
|
+
{
|
|
133
|
+
instances = setup.EnumAllInstances();
|
|
134
|
+
ISetupInstance[] one = new ISetupInstance[1];
|
|
135
|
+
while (true)
|
|
136
|
+
{
|
|
137
|
+
int fetched;
|
|
138
|
+
instances.Next(1, one, out fetched);
|
|
139
|
+
if (fetched == 0)
|
|
140
|
+
{
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
ISetupInstance2 instance = (ISetupInstance2)one[0];
|
|
144
|
+
try
|
|
145
|
+
{
|
|
146
|
+
found.Add(Describe(instance));
|
|
147
|
+
}
|
|
148
|
+
finally
|
|
149
|
+
{
|
|
150
|
+
Marshal.ReleaseComObject(instance);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
finally
|
|
155
|
+
{
|
|
156
|
+
if (instances != null)
|
|
157
|
+
{
|
|
158
|
+
Marshal.ReleaseComObject(instances);
|
|
159
|
+
}
|
|
160
|
+
Marshal.ReleaseComObject(setup);
|
|
161
|
+
}
|
|
162
|
+
return found.ToArray();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private static SetupInstanceInfo Describe(ISetupInstance2 instance)
|
|
166
|
+
{
|
|
167
|
+
SetupInstanceInfo info = new SetupInstanceInfo();
|
|
168
|
+
info.InstanceId = instance.GetInstanceId();
|
|
169
|
+
info.InstallationPath = instance.GetInstallationPath();
|
|
170
|
+
info.InstallationVersion = instance.GetInstallationVersion();
|
|
171
|
+
info.State = instance.GetState();
|
|
172
|
+
ISetupPackageReference product = instance.GetProduct();
|
|
173
|
+
if (product == null)
|
|
174
|
+
{
|
|
175
|
+
info.ProductId = "";
|
|
176
|
+
}
|
|
177
|
+
else
|
|
178
|
+
{
|
|
179
|
+
try
|
|
180
|
+
{
|
|
181
|
+
info.ProductId = product.GetId();
|
|
182
|
+
}
|
|
183
|
+
finally
|
|
184
|
+
{
|
|
185
|
+
Marshal.ReleaseComObject(product);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
info.IsComplete = instance.IsComplete();
|
|
189
|
+
info.IsLaunchable = instance.IsLaunchable();
|
|
190
|
+
ISetupPackageReference[] packages = instance.GetPackages();
|
|
191
|
+
List<string> ids = new List<string>();
|
|
192
|
+
if (packages != null)
|
|
193
|
+
{
|
|
194
|
+
foreach (ISetupPackageReference package in packages)
|
|
195
|
+
{
|
|
196
|
+
try
|
|
197
|
+
{
|
|
198
|
+
ids.Add(package.GetId());
|
|
199
|
+
}
|
|
200
|
+
finally
|
|
201
|
+
{
|
|
202
|
+
Marshal.ReleaseComObject(package);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
info.Packages = ids.ToArray();
|
|
207
|
+
return info;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#Requires -Version 5.1
|
|
2
|
+
# Looks for Visual Studio the way UnrealBuildTool does (guest/toolchains/engines/unreal-engines.ts runs it; the
|
|
3
|
+
# verdict is decided in vs-check.ts): every instance the Setup Configuration API lists (csharp\VsSetup.cs), the MSVC
|
|
4
|
+
# toolchains under each one's VC\Tools\MSVC that have the x64 compiler, and the Windows SDKs under each KitsRoot10 the
|
|
5
|
+
# registry names (HKLM in both views, HKCU) that have windows.h and the x64 kernel32.lib. Writes JSON to -ResultFile.
|
|
6
|
+
param([Parameter(Mandatory = $true)][string]$ResultFile)
|
|
7
|
+
$ErrorActionPreference = 'Stop'
|
|
8
|
+
|
|
9
|
+
Add-Type -Path (Join-Path $PSScriptRoot '..\csharp\VsSetup.cs')
|
|
10
|
+
|
|
11
|
+
$instances = New-Object System.Collections.ArrayList
|
|
12
|
+
$setupError = ''
|
|
13
|
+
try {
|
|
14
|
+
foreach ($i in [AgentSandbox.VsSetup]::AllInstances()) {
|
|
15
|
+
$toolchains = New-Object System.Collections.ArrayList
|
|
16
|
+
$msvc = Join-Path $i.InstallationPath 'VC\Tools\MSVC'
|
|
17
|
+
if (Test-Path -LiteralPath $msvc -PathType Container) {
|
|
18
|
+
foreach ($dir in Get-ChildItem -LiteralPath $msvc -Directory) {
|
|
19
|
+
$cl = Join-Path $dir.FullName 'bin\Hostx64\x64\cl.exe'
|
|
20
|
+
$link = Join-Path $dir.FullName 'bin\Hostx64\x64\link.exe'
|
|
21
|
+
[void]$toolchains.Add([ordered]@{
|
|
22
|
+
version = $dir.Name
|
|
23
|
+
cl = (Test-Path -LiteralPath $cl -PathType Leaf)
|
|
24
|
+
link = (Test-Path -LiteralPath $link -PathType Leaf)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
$wanted = @('Microsoft.VisualStudio.Component.VC.Tools.x86.x64', 'Microsoft.VisualStudio.Workload.NativeGame',
|
|
29
|
+
'Microsoft.VisualStudio.Workload.VCTools', 'Component.Unreal', 'Component.Unreal.Ide')
|
|
30
|
+
[void]$instances.Add([ordered]@{
|
|
31
|
+
instanceId = $i.InstanceId
|
|
32
|
+
installationPath = $i.InstallationPath
|
|
33
|
+
installationVersion = $i.InstallationVersion
|
|
34
|
+
productId = $i.ProductId
|
|
35
|
+
state = [int64]$i.State
|
|
36
|
+
isComplete = $i.IsComplete
|
|
37
|
+
isLaunchable = $i.IsLaunchable
|
|
38
|
+
packages = @($i.Packages | Where-Object { $wanted -contains $_ })
|
|
39
|
+
packageCount = @($i.Packages).Count
|
|
40
|
+
toolchains = @($toolchains)
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
$setupError = $_.Exception.Message
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
$roots = New-Object System.Collections.ArrayList
|
|
48
|
+
$places = @(
|
|
49
|
+
@{ hive = [Microsoft.Win32.RegistryHive]::LocalMachine; view = [Microsoft.Win32.RegistryView]::Registry64; name = 'HKLM (64-bit)' },
|
|
50
|
+
@{ hive = [Microsoft.Win32.RegistryHive]::LocalMachine; view = [Microsoft.Win32.RegistryView]::Registry32; name = 'HKLM (32-bit)' },
|
|
51
|
+
@{ hive = [Microsoft.Win32.RegistryHive]::CurrentUser; view = [Microsoft.Win32.RegistryView]::Registry64; name = 'HKCU' }
|
|
52
|
+
)
|
|
53
|
+
foreach ($place in $places) {
|
|
54
|
+
$base = [Microsoft.Win32.RegistryKey]::OpenBaseKey($place.hive, $place.view)
|
|
55
|
+
try {
|
|
56
|
+
$key = $base.OpenSubKey('SOFTWARE\Microsoft\Windows Kits\Installed Roots')
|
|
57
|
+
if ($key) {
|
|
58
|
+
$value = [string]$key.GetValue('KitsRoot10')
|
|
59
|
+
$key.Close()
|
|
60
|
+
if ($value) { [void]$roots.Add([ordered]@{ where = $place.name; path = $value }) }
|
|
61
|
+
}
|
|
62
|
+
} finally {
|
|
63
|
+
$base.Close()
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
$sdks = New-Object System.Collections.ArrayList
|
|
68
|
+
$seen = @{}
|
|
69
|
+
foreach ($root in $roots) {
|
|
70
|
+
$include = Join-Path $root.path 'Include'
|
|
71
|
+
if ($seen.ContainsKey($include.ToLowerInvariant())) { continue }
|
|
72
|
+
$seen[$include.ToLowerInvariant()] = $true
|
|
73
|
+
if (-not (Test-Path -LiteralPath $include -PathType Container)) { continue }
|
|
74
|
+
foreach ($dir in Get-ChildItem -LiteralPath $include -Directory) {
|
|
75
|
+
if ($dir.Name -notmatch '^10\.\d+\.\d+\.\d+$') { continue }
|
|
76
|
+
[void]$sdks.Add([ordered]@{
|
|
77
|
+
version = $dir.Name
|
|
78
|
+
root = $root.path
|
|
79
|
+
windowsH = (Test-Path -LiteralPath (Join-Path $dir.FullName 'um\windows.h') -PathType Leaf)
|
|
80
|
+
kernel32 = (Test-Path -LiteralPath (Join-Path $root.path ('Lib\' + $dir.Name + '\um\x64\kernel32.lib')) -PathType Leaf)
|
|
81
|
+
ucrt = (Test-Path -LiteralPath (Join-Path $root.path ('Lib\' + $dir.Name + '\ucrt\x64\ucrt.lib')) -PathType Leaf)
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
$result = [ordered]@{
|
|
87
|
+
setupError = $setupError
|
|
88
|
+
instances = @($instances)
|
|
89
|
+
kitsRoots = @($roots)
|
|
90
|
+
sdks = @($sdks)
|
|
91
|
+
}
|
|
92
|
+
$json = ConvertTo-Json -InputObject $result -Depth 6
|
|
93
|
+
[System.IO.File]::WriteAllText($ResultFile, $json, (New-Object System.Text.UTF8Encoding($false)))
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#Requires -Version 5.1
|
|
2
|
+
# Puts a saved Visual Studio back at boot, in seconds (guest/toolchains/native/visual-studio.ts; what goes where is
|
|
3
|
+
# decided in vs-persist.ts): the small folders programs look for at fixed paths are copied back, then the registry
|
|
4
|
+
# values that point at the big folders on the data disk and the Setup Configuration COM class are written. -PlanFile is
|
|
5
|
+
# JSON written by the runtime:
|
|
6
|
+
# copies: [{ name, from, to, mode: 'all' | 'missing' }] 'all': robocopy /E (only what differs is copied);
|
|
7
|
+
# 'missing': each subfolder only when the target has none
|
|
8
|
+
# registry: [{ view: '64'|'32', key, name, kind: 'string'|'expand'|'dword', value }] under HKLM ('' = default)
|
|
9
|
+
# Safe to run again. Exit 0 when everything is in place, 1 when a copy failed, 2 when a registry value could not be set.
|
|
10
|
+
param([Parameter(Mandatory = $true)][string]$PlanFile)
|
|
11
|
+
$ErrorActionPreference = 'Stop'
|
|
12
|
+
|
|
13
|
+
$plan = Get-Content -LiteralPath $PlanFile -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
14
|
+
$robocopy = Join-Path $env:SystemRoot 'System32\Robocopy.exe'
|
|
15
|
+
|
|
16
|
+
function Copy-Folder([string]$From, [string]$To) {
|
|
17
|
+
New-Item -ItemType Directory -Force -Path $To | Out-Null
|
|
18
|
+
& $robocopy $From $To /E /COPY:DAT /XJ /R:1 /W:1 /MT:16 /NP /NFL /NDL /NJH /NJS | Where-Object { $_ -and $_.Trim() } | Out-Host
|
|
19
|
+
return $LASTEXITCODE
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
$copied = 0
|
|
23
|
+
$failed = New-Object System.Collections.ArrayList
|
|
24
|
+
foreach ($copy in @($plan.copies)) {
|
|
25
|
+
if (-not (Test-Path -LiteralPath $copy.from -PathType Container)) {
|
|
26
|
+
[void]$failed.Add($copy.name + ' (' + $copy.from + ' is missing)')
|
|
27
|
+
continue
|
|
28
|
+
}
|
|
29
|
+
if ($copy.mode -eq 'missing') {
|
|
30
|
+
foreach ($child in Get-ChildItem -LiteralPath $copy.from -Directory) {
|
|
31
|
+
$target = Join-Path $copy.to $child.Name
|
|
32
|
+
if (Test-Path -LiteralPath $target) { continue }
|
|
33
|
+
$code = Copy-Folder -From $child.FullName -To $target
|
|
34
|
+
if ($code -ge 8) { [void]$failed.Add($copy.name + '\' + $child.Name + ' (robocopy ' + $code + ')') }
|
|
35
|
+
}
|
|
36
|
+
$copied++
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
$code = Copy-Folder -From $copy.from -To $copy.to
|
|
40
|
+
if ($code -ge 8) { [void]$failed.Add($copy.name + ' (robocopy ' + $code + ')') } else { $copied++ }
|
|
41
|
+
}
|
|
42
|
+
if ($failed.Count) {
|
|
43
|
+
Write-Error ('restore-visual-studio: could not copy ' + ($failed -join ', '))
|
|
44
|
+
exit 1
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
$set = 0
|
|
48
|
+
$bad = New-Object System.Collections.ArrayList
|
|
49
|
+
foreach ($entry in @($plan.registry)) {
|
|
50
|
+
$view = [Microsoft.Win32.RegistryView]::Registry64
|
|
51
|
+
if ($entry.view -eq '32') { $view = [Microsoft.Win32.RegistryView]::Registry32 }
|
|
52
|
+
$base = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $view)
|
|
53
|
+
try {
|
|
54
|
+
$key = $base.CreateSubKey([string]$entry.key)
|
|
55
|
+
try {
|
|
56
|
+
if ($entry.kind -eq 'dword') {
|
|
57
|
+
$key.SetValue([string]$entry.name, [int]$entry.value, [Microsoft.Win32.RegistryValueKind]::DWord)
|
|
58
|
+
} elseif ($entry.kind -eq 'expand') {
|
|
59
|
+
$key.SetValue([string]$entry.name, [string]$entry.value, [Microsoft.Win32.RegistryValueKind]::ExpandString)
|
|
60
|
+
} else {
|
|
61
|
+
$key.SetValue([string]$entry.name, [string]$entry.value, [Microsoft.Win32.RegistryValueKind]::String)
|
|
62
|
+
}
|
|
63
|
+
$set++
|
|
64
|
+
} finally {
|
|
65
|
+
$key.Close()
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
[void]$bad.Add($entry.view + ':' + $entry.key + '\' + $entry.name + ' (' + $_.Exception.Message + ')')
|
|
69
|
+
} finally {
|
|
70
|
+
$base.Close()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if ($bad.Count) {
|
|
74
|
+
Write-Error ('restore-visual-studio: could not set ' + ($bad -join '; '))
|
|
75
|
+
exit 2
|
|
76
|
+
}
|
|
77
|
+
Write-Output ('Restored Visual Studio: ' + $copied + ' folders in place, ' + $set + ' registry values set')
|
|
78
|
+
exit 0
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#Requires -Version 5.1
|
|
2
|
+
# Saves a finished Visual Studio install onto the data disk, once (guest/toolchains/native/visual-studio.ts; what goes
|
|
3
|
+
# where is decided in vs-persist.ts). -PlanFile is JSON written by the runtime:
|
|
4
|
+
# copies: [{ name, from, to, optional }] each mirrored with robocopy (/MIR); a missing optional one is skipped
|
|
5
|
+
# registry: [{ view: '64'|'32', key, names: [..] | null, recurse }] string and DWORD values read under HKLM
|
|
6
|
+
# resultFile: where the result goes, as JSON: { copied: [names], registry: [{ view, key, name, kind, value }] }
|
|
7
|
+
# -LowPriority runs it (and robocopy) below normal priority. Safe to run again: robocopy copies only what differs.
|
|
8
|
+
# Exit 0 when every copy worked, 1 when one failed (no result file then), 2 for a bad plan.
|
|
9
|
+
param(
|
|
10
|
+
[Parameter(Mandatory = $true)][string]$PlanFile,
|
|
11
|
+
[switch]$LowPriority
|
|
12
|
+
)
|
|
13
|
+
$ErrorActionPreference = 'Stop'
|
|
14
|
+
|
|
15
|
+
if ($LowPriority) {
|
|
16
|
+
try {
|
|
17
|
+
[System.Diagnostics.Process]::GetCurrentProcess().PriorityClass = [System.Diagnostics.ProcessPriorityClass]::BelowNormal
|
|
18
|
+
} catch {
|
|
19
|
+
# Normal priority only makes the copy compete a little more with the sessions.
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
$plan = Get-Content -LiteralPath $PlanFile -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
24
|
+
if (-not $plan.resultFile -or -not $plan.copies) {
|
|
25
|
+
Write-Error 'save-visual-studio: the plan has no copies or no result file'
|
|
26
|
+
exit 2
|
|
27
|
+
}
|
|
28
|
+
$robocopy = Join-Path $env:SystemRoot 'System32\Robocopy.exe'
|
|
29
|
+
|
|
30
|
+
function Copy-Folder([string]$From, [string]$To) {
|
|
31
|
+
New-Item -ItemType Directory -Force -Path $To | Out-Null
|
|
32
|
+
# /MIR drops files a previous capture left; /XJ skips links (the data disk refuses them); /A-:R keeps read-only
|
|
33
|
+
# files rewritable by the next capture.
|
|
34
|
+
& $robocopy $From $To /MIR /COPY:DAT /XJ /A-:R /R:1 /W:1 /MT:16 /NP /NFL /NDL /NJH /NJS | Where-Object { $_ -and $_.Trim() } | Out-Host
|
|
35
|
+
return $LASTEXITCODE
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
$copied = New-Object System.Collections.ArrayList
|
|
39
|
+
$failed = New-Object System.Collections.ArrayList
|
|
40
|
+
foreach ($copy in @($plan.copies)) {
|
|
41
|
+
if (-not (Test-Path -LiteralPath $copy.from -PathType Container)) {
|
|
42
|
+
if ($copy.optional) { continue }
|
|
43
|
+
[void]$failed.Add($copy.name + ' (' + $copy.from + ' is missing)')
|
|
44
|
+
continue
|
|
45
|
+
}
|
|
46
|
+
$code = Copy-Folder -From $copy.from -To $copy.to
|
|
47
|
+
if ($code -ge 8) { [void]$failed.Add($copy.name + ' (robocopy ' + $code + ')') } else { [void]$copied.Add([string]$copy.name) }
|
|
48
|
+
}
|
|
49
|
+
if ($failed.Count) {
|
|
50
|
+
Write-Error ('save-visual-studio: could not save ' + ($failed -join ', '))
|
|
51
|
+
exit 1
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function Get-View([string]$View) {
|
|
55
|
+
if ($View -eq '32') { return [Microsoft.Win32.RegistryView]::Registry32 }
|
|
56
|
+
return [Microsoft.Win32.RegistryView]::Registry64
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function Read-Values([Microsoft.Win32.RegistryKey]$Key, [string]$Path, [string]$View, $Names, [bool]$Recurse, $Out) {
|
|
60
|
+
$options = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
|
|
61
|
+
foreach ($name in $Key.GetValueNames()) {
|
|
62
|
+
if ($null -ne $Names -and -not ($Names -contains $name)) { continue }
|
|
63
|
+
$kind = $Key.GetValueKind($name)
|
|
64
|
+
$value = $Key.GetValue($name, $null, $options)
|
|
65
|
+
$label = $null
|
|
66
|
+
if ($kind -eq [Microsoft.Win32.RegistryValueKind]::String) { $label = 'string' }
|
|
67
|
+
elseif ($kind -eq [Microsoft.Win32.RegistryValueKind]::ExpandString) { $label = 'expand' }
|
|
68
|
+
elseif ($kind -eq [Microsoft.Win32.RegistryValueKind]::DWord) { $label = 'dword'; $value = [int]$value }
|
|
69
|
+
if ($null -eq $label -or $null -eq $value) { continue }
|
|
70
|
+
[void]$Out.Add([ordered]@{ view = $View; key = $Path; name = $name; kind = $label; value = $value })
|
|
71
|
+
}
|
|
72
|
+
if (-not $Recurse) { return }
|
|
73
|
+
foreach ($sub in $Key.GetSubKeyNames()) {
|
|
74
|
+
$child = $Key.OpenSubKey($sub)
|
|
75
|
+
if ($null -eq $child) { continue }
|
|
76
|
+
try {
|
|
77
|
+
Read-Values -Key $child -Path ($Path + '\' + $sub) -View $View -Names $Names -Recurse $true -Out $Out
|
|
78
|
+
} finally {
|
|
79
|
+
$child.Close()
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
$values = New-Object System.Collections.ArrayList
|
|
85
|
+
foreach ($read in @($plan.registry)) {
|
|
86
|
+
$base = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, (Get-View $read.view))
|
|
87
|
+
try {
|
|
88
|
+
$key = $base.OpenSubKey([string]$read.key)
|
|
89
|
+
if ($null -eq $key) { continue }
|
|
90
|
+
try {
|
|
91
|
+
$names = $null
|
|
92
|
+
if ($null -ne $read.names) { $names = @($read.names) }
|
|
93
|
+
Read-Values -Key $key -Path ([string]$read.key) -View ([string]$read.view) -Names $names -Recurse ([bool]$read.recurse) -Out $values
|
|
94
|
+
} finally {
|
|
95
|
+
$key.Close()
|
|
96
|
+
}
|
|
97
|
+
} finally {
|
|
98
|
+
$base.Close()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
$result = [ordered]@{ copied = @($copied.ToArray()); registry = @($values.ToArray()) }
|
|
103
|
+
$json = ConvertTo-Json -InputObject $result -Depth 6
|
|
104
|
+
[System.IO.File]::WriteAllText($plan.resultFile, $json, (New-Object System.Text.UTF8Encoding $false))
|
|
105
|
+
Write-Output ('Saved Visual Studio: ' + $copied.Count + ' folders, ' + $values.Count + ' registry values')
|
|
106
|
+
exit 0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#Requires -Version 5.1
|
|
2
|
+
# Writes string registry values from a plan (guest/toolchains/engines/unreal-engines.ts: the Unreal engines'
|
|
3
|
+
# registration and the .uproject file association; what goes where is decided in shared/unreal/engines.ts). -PlanFile
|
|
4
|
+
# is JSON written by the runtime:
|
|
5
|
+
# values: [{ hive: 'HKLM' | 'HKCU', key, name, value }] 64-bit view, '' = the default value
|
|
6
|
+
# Safe to run again. Exit 0 when every value is set, 2 when one could not be.
|
|
7
|
+
param([Parameter(Mandatory = $true)][string]$PlanFile)
|
|
8
|
+
$ErrorActionPreference = 'Stop'
|
|
9
|
+
|
|
10
|
+
$plan = Get-Content -LiteralPath $PlanFile -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
11
|
+
$failed = New-Object System.Collections.ArrayList
|
|
12
|
+
$set = 0
|
|
13
|
+
foreach ($v in @($plan.values)) {
|
|
14
|
+
$hive = if ($v.hive -eq 'HKLM') { [Microsoft.Win32.RegistryHive]::LocalMachine } else { [Microsoft.Win32.RegistryHive]::CurrentUser }
|
|
15
|
+
$base = [Microsoft.Win32.RegistryKey]::OpenBaseKey($hive, [Microsoft.Win32.RegistryView]::Registry64)
|
|
16
|
+
try {
|
|
17
|
+
$key = $base.CreateSubKey([string]$v.key)
|
|
18
|
+
try {
|
|
19
|
+
$key.SetValue([string]$v.name, [string]$v.value, [Microsoft.Win32.RegistryValueKind]::String)
|
|
20
|
+
$set++
|
|
21
|
+
} finally {
|
|
22
|
+
$key.Close()
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
[void]$failed.Add($v.hive + '\' + $v.key + ' ' + $v.name + ' (' + $_.Exception.Message + ')')
|
|
26
|
+
} finally {
|
|
27
|
+
$base.Close()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if ($failed.Count) {
|
|
31
|
+
Write-Host ('Could not set: ' + ($failed -join '; '))
|
|
32
|
+
exit 2
|
|
33
|
+
}
|
|
34
|
+
Write-Host ('Set ' + $set + ' registry values')
|
|
35
|
+
exit 0
|
|
@@ -554,6 +554,10 @@
|
|
|
554
554
|
},
|
|
555
555
|
"unrealEngines": {
|
|
556
556
|
"anyOf": [
|
|
557
|
+
{
|
|
558
|
+
"type": "string",
|
|
559
|
+
"const": "auto"
|
|
560
|
+
},
|
|
557
561
|
{
|
|
558
562
|
"type": "boolean"
|
|
559
563
|
},
|
|
@@ -565,7 +569,29 @@
|
|
|
565
569
|
}
|
|
566
570
|
}
|
|
567
571
|
],
|
|
568
|
-
"description": "Unreal Engine versions installed with the Epic Games Launcher
|
|
572
|
+
"description": "Unreal Engine versions installed on this PC (with the Epic Games Launcher, or source builds it lists), read-only in the sandbox under C:\\PcInstalls\\unreal and registered there, so projects build with them without a download. \"auto\" = all of them whenever the sandbox is set up for Unreal, true = always, false = never, or a list (e.g. [\"5.4\"])."
|
|
573
|
+
},
|
|
574
|
+
"unrealEngineFolders": {
|
|
575
|
+
"maxItems": 8,
|
|
576
|
+
"type": "array",
|
|
577
|
+
"items": {
|
|
578
|
+
"type": "string",
|
|
579
|
+
"minLength": 3,
|
|
580
|
+
"maxLength": 260
|
|
581
|
+
},
|
|
582
|
+
"description": "Unreal Engine folders of this PC to use in the sandbox, writable (a source build, or a copy you build plugins into): each must hold Engine\\Build\\Build.version. Mapped under C:\\PcInstalls\\unreal and registered there."
|
|
583
|
+
},
|
|
584
|
+
"unrealAssets": {
|
|
585
|
+
"anyOf": [
|
|
586
|
+
{
|
|
587
|
+
"type": "string",
|
|
588
|
+
"const": "auto"
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
"type": "boolean"
|
|
592
|
+
}
|
|
593
|
+
],
|
|
594
|
+
"description": "The Epic Games Launcher's vault cache of this PC (the Fab and Marketplace packs you downloaded), read-only in the sandbox at C:\\PcInstalls\\unreal\\Vault: what you download on your PC is there for the agents at once. \"auto\" = whenever the sandbox is set up for Unreal, true = always, false = never."
|
|
569
595
|
},
|
|
570
596
|
"unityEditors": {
|
|
571
597
|
"anyOf": [
|
|
@@ -800,7 +826,7 @@
|
|
|
800
826
|
"lld",
|
|
801
827
|
"gnu"
|
|
802
828
|
],
|
|
803
|
-
"description": "
|
|
829
|
+
"description": "\"lld\" (default) links with Rust's own lld: through MinGW's gcc on the GNU host (much less memory than GNU ld), and instead of link.exe on the MSVC host (link.exe writes executables into mapped folders as all zeros: os error 1392). \"gnu\" keeps GNU ld / link.exe."
|
|
804
830
|
},
|
|
805
831
|
"linkSlots": {
|
|
806
832
|
"anyOf": [
|
|
@@ -864,7 +890,7 @@
|
|
|
864
890
|
"const": "auto"
|
|
865
891
|
}
|
|
866
892
|
],
|
|
867
|
-
"description": "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime.
|
|
893
|
+
"description": "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. Visual Studio is installed once and kept on the data disk (~6.5 GB); later boots put it back in seconds. The engine itself comes from the Epic Games Launcher or its source. true, false, or \"auto\" = only when the project has a .uproject or .uplugin."
|
|
868
894
|
},
|
|
869
895
|
"acceptLicense": {
|
|
870
896
|
"type": "boolean",
|
|
@@ -877,17 +903,13 @@
|
|
|
877
903
|
},
|
|
878
904
|
"description": "More Visual Studio workload or component IDs to add, e.g. [\"Microsoft.VisualStudio.Component.VC.Llvm.Clang\"]."
|
|
879
905
|
},
|
|
880
|
-
"keepInstallFiles": {
|
|
881
|
-
"type": "boolean",
|
|
882
|
-
"description": "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
|
|
883
|
-
},
|
|
884
906
|
"visualStudio": {
|
|
885
907
|
"type": "string",
|
|
886
908
|
"enum": [
|
|
887
909
|
"full",
|
|
888
|
-
"
|
|
910
|
+
"buildtools"
|
|
889
911
|
],
|
|
890
|
-
"description": "\"full\":
|
|
912
|
+
"description": "\"full\": Visual Studio Community with the C++ game workload (the IDE, its debugger and Unreal integration). \"buildtools\": only the Visual Studio Build Tools (MSVC, the Windows SDK and the .NET Framework parts UnrealBuildTool needs; no IDE). Either is installed once and kept on the data disk (tools\\visualstudio\\persist, ~6.5 GB for Community); later boots put it back in seconds."
|
|
891
913
|
},
|
|
892
914
|
"persistEngines": {
|
|
893
915
|
"type": "boolean",
|
|
@@ -2030,6 +2052,13 @@
|
|
|
2030
2052
|
"gitleaks",
|
|
2031
2053
|
"ast-grep",
|
|
2032
2054
|
"rust-analyzer",
|
|
2055
|
+
"krita",
|
|
2056
|
+
"inkscape",
|
|
2057
|
+
"audacity",
|
|
2058
|
+
"renderdoc",
|
|
2059
|
+
"f3d",
|
|
2060
|
+
"imagemagick",
|
|
2061
|
+
"nomacs",
|
|
2033
2062
|
"lua-language-server",
|
|
2034
2063
|
"stylua",
|
|
2035
2064
|
"selene",
|