diff --git a/ProExporter/Buttons.cs b/ProExporter/Buttons.cs
index ff166a7..2e81cb5 100644
--- a/ProExporter/Buttons.cs
+++ b/ProExporter/Buttons.cs
@@ -203,12 +203,19 @@ private void OpenTerminalWithProEnv()
// Get current ArcGIS Pro process ID for arcpy to connect to
var proProcessId = Process.GetCurrentProcess().Id;
+ // Ensure the Python startup hook exists so any python process launched from this terminal
+ // self-heals stale ArcGISProTemp* workspace paths.
+ EnsurePythonStartupHook(projectDir);
+
string args;
if (File.Exists(activateBat) && File.Exists(pythonEnvUtils))
{
// Set ARCGISPRO_PID so arcpy connects to this running Pro session
- // This prevents "Directory does not exist" errors with stale temp paths
+ // Set ARCGISPRO_PROJECT_DIR and add .arcgispro/ to PYTHONPATH so Python auto-imports sitecustomize.py
+ // This prevents "Directory does not exist" errors with stale temp paths.
args = $"/k \"set ARCGISPRO_PID={proProcessId} && " +
+ $"set ARCGISPRO_PROJECT_DIR=\"{projectDir}\" && " +
+ $"set PYTHONPATH=\"{Path.Combine(projectDir, ".arcgispro")}\";%PYTHONPATH% && " +
$"set CONDA_SKIPCHECK=1 && " +
$"for /f \"delims=\" %i in ('\"{pythonEnvUtils}\"') do @call \"{activateBat}\" \"%i\" && " +
$"cd /d \"{projectDir}\"\"";
@@ -216,7 +223,10 @@ private void OpenTerminalWithProEnv()
else
{
// Fallback: set PID and open at project folder
- args = $"/k \"set ARCGISPRO_PID={proProcessId} && cd /d \"{projectDir}\"\"";
+ args = $"/k \"set ARCGISPRO_PID={proProcessId} && " +
+ $"set ARCGISPRO_PROJECT_DIR=\"{projectDir}\" && " +
+ $"set PYTHONPATH=\"{Path.Combine(projectDir, ".arcgispro")}\";%PYTHONPATH% && " +
+ $"cd /d \"{projectDir}\"\"";
}
try
@@ -256,11 +266,11 @@ private void ExportSessionInfo(string projectDir)
proTempPath = Path.Combine(Path.GetTempPath(), $"ArcGISProTemp{processId}")
};
- var json = JsonSerializer.Serialize(sessionInfo, new JsonSerializerOptions
- {
- WriteIndented = true
+ var json = JsonSerializer.Serialize(sessionInfo, new JsonSerializerOptions
+ {
+ WriteIndented = true
});
-
+
File.WriteAllText(Path.Combine(arcgisproFolder, "session.json"), json);
}
catch
@@ -268,5 +278,96 @@ private void ExportSessionInfo(string projectDir)
// Non-critical - continue even if session export fails
}
}
+
+ ///
+ /// Writes a Python sitecustomize.py into .arcgispro so any python process started from the Terminal
+ /// can automatically repair stale workspace paths (ArcGISProTemp*) and prefer a stable project scratch.gdb.
+ ///
+ private void EnsurePythonStartupHook(string projectDir)
+ {
+ try
+ {
+ var arcgisproFolder = Path.Combine(projectDir, ".arcgispro");
+ Directory.CreateDirectory(arcgisproFolder);
+
+ var hookPath = Path.Combine(arcgisproFolder, "sitecustomize.py");
+
+ // Keep this intentionally small, defensive, and silent.
+ // - If arcpy isn't available, do nothing.
+ // - If scratch/workspace points at a missing ArcGISProTemp* path, clear it.
+ // - If we can, set scratch/workspace to /scratch.gdb (create if missing).
+ var code = @"# Auto-run hook for ArcGIS Pro Terminal sessions.
+# Loaded automatically by Python if this folder is on PYTHONPATH.
+
+import os
+
+
+def _exists(p: str) -> bool:
+ try:
+ return bool(p) and os.path.exists(p)
+ except Exception:
+ return False
+
+
+def _looks_like_stale_pro_temp(p: str) -> bool:
+ try:
+ if not p:
+ return False
+ s = str(p)
+ return ("ArcGISProTemp" in s) and (not os.path.exists(s))
+ except Exception:
+ return False
+
+
+def _main() -> None:
+ try:
+ import arcpy # type: ignore
+ except Exception:
+ return
+
+ project_dir = (os.environ.get("ARCGISPRO_PROJECT_DIR") or "").strip().strip('"')
+
+ # 1) Clear stale ArcGISProTemp* references if present
+ try:
+ sw = getattr(arcpy.env, "scratchWorkspace", None)
+ if _looks_like_stale_pro_temp(sw):
+ arcpy.ClearEnvironment("scratchWorkspace")
+ except Exception:
+ pass
+
+ try:
+ ws = getattr(arcpy.env, "workspace", None)
+ if _looks_like_stale_pro_temp(ws):
+ arcpy.ClearEnvironment("workspace")
+ except Exception:
+ pass
+
+ # 2) Prefer a stable, project-local scratch.gdb
+ if project_dir and _exists(project_dir):
+ scratch_gdb = os.path.join(project_dir, "scratch.gdb")
+ try:
+ if not arcpy.Exists(scratch_gdb):
+ arcpy.management.CreateFileGDB(project_dir, "scratch.gdb")
+ arcpy.env.scratchWorkspace = scratch_gdb
+ arcpy.env.workspace = scratch_gdb
+ except Exception:
+ # Don't block user scripts if we can't create/use scratch.gdb.
+ pass
+
+
+try:
+ _main()
+except Exception:
+ # Never crash Python startup.
+ pass
+";
+
+ File.WriteAllText(hookPath, code);
+ }
+ catch
+ {
+ // Non-critical - continue even if hook write fails
+ }
+ }
}
}