feat: enhance Windows compatibility for LibreOffice checks and subprocess handling

This commit is contained in:
sudipnext 2026-03-25 09:24:00 +05:45
parent 93ef13604a
commit 43f433597b
2 changed files with 44 additions and 1 deletions

View file

@ -275,6 +275,12 @@ export async function isLibreOfficeInstalled(): Promise<LibreOfficeCheckResult>
// --- Step 1: check well-known paths synchronously (no exec overhead) ---
for (const candidate of getCandidatePaths()) {
if (fs.existsSync(candidate)) {
// On Windows, avoid probing with "--version" because some LibreOffice
// builds open a transient console window for this command.
if (process.platform === "win32") {
return { installed: true, path: candidate };
}
// Binary found at a known location try to get the version string.
try {
const quoted = `"${candidate}"`;
@ -291,6 +297,26 @@ export async function isLibreOfficeInstalled(): Promise<LibreOfficeCheckResult>
}
// --- Step 2: try the PATH-based command ---
if (process.platform === "win32") {
try {
// Use "where" for PATH detection without launching LibreOffice itself.
const { stdout } = await execAsync("where soffice.exe", {
timeout: 8_000,
windowsHide: true,
});
const firstPath = stdout
.split(/\r?\n/)
.map((line) => line.trim())
.find((line) => line.length > 0);
if (firstPath) {
return { installed: true, path: firstPath };
}
} catch {
// Keep behavior: if PATH lookup fails, report not installed.
}
return { installed: false };
}
try {
const { stdout } = await execAsync("soffice --version", {
timeout: 8_000,

View file

@ -26,7 +26,23 @@ def _get_soffice_binary() -> str:
environment variable. Falling back to the bare ``"soffice"`` command keeps
Docker / server deployments working unchanged.
"""
return os.environ.get("SOFFICE_PATH") or "soffice"
configured = os.environ.get("SOFFICE_PATH")
if configured:
return configured
return "soffice.exe" if os.name == "nt" else "soffice"
def _windows_hidden_subprocess_kwargs() -> Dict[str, object]:
"""Return subprocess kwargs that suppress Windows console windows."""
if os.name != "nt":
return {}
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
return {
"creationflags": getattr(subprocess, "CREATE_NO_WINDOW", 0),
"startupinfo": startupinfo,
}
PPTX_SLIDES_ROUTER = APIRouter(prefix="/pptx-slides", tags=["PPTX Slides"])
@ -596,6 +612,7 @@ async def _convert_pptx_to_pdf(pptx_path: str, temp_dir: str) -> str:
text=True,
timeout=500,
env=env,
**_windows_hidden_subprocess_kwargs(),
)
print(f"LibreOffice PDF conversion output: {result.stdout}")