Files
DCIT/DCIT.Core/Services/RuntimeEnvironmentValidationService.cs
2026-07-13 10:04:36 +08:00

143 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO;
using DCIT.Core.Models;
namespace DCIT.Core.Services
{
public class RuntimeEnvironmentValidationService
{
private static readonly string[] WpsProgIds =
{
"KWPS.Application",
"kwps.Application",
"WPS.Application",
"wps.Application",
};
private readonly string _startupDirectory;
public RuntimeEnvironmentValidationService(string startupDirectory = null)
{
_startupDirectory = string.IsNullOrWhiteSpace(startupDirectory)
? AppContext.BaseDirectory
: startupDirectory;
}
public RuntimeEnvironmentValidationResult Validate()
{
var result = new RuntimeEnvironmentValidationResult
{
StartupDirectory = _startupDirectory,
};
result.IsStartupDirectoryWritable = CanWriteToDirectory(_startupDirectory);
if (!result.IsStartupDirectoryWritable)
{
result.BlockingIssues.Add("程序启动目录不可写。请将程序部署到当前用户具有写权限的目录后再启动。");
}
result.ResolvedAutomationProgId = ResolveAutomationProgId();
if (string.IsNullOrWhiteSpace(result.ResolvedAutomationProgId))
{
result.BlockingIssues.Add("未检测到可自动化的 Microsoft Word 或 WPS 组件。当前环境无法满足目录/域刷新及 .doc 处理要求。");
}
result.ResolvedDocToPath = ResolveDocToPath();
if (string.IsNullOrWhiteSpace(result.ResolvedDocToPath))
{
result.Warnings.Add("未检测到 docto.exe.doc 兼容性将仅依赖 Word/WPS 自动化链路。");
}
return result;
}
protected virtual IEnumerable<string> GetOfficeAutomationProgIds()
{
yield return "Word.Application";
foreach (var progId in WpsProgIds)
{
yield return progId;
}
}
protected virtual bool IsProgIdRegistered(string progId)
{
return !string.IsNullOrWhiteSpace(progId)
&& Type.GetTypeFromProgID(progId, false) != null;
}
protected virtual string ResolveDocToPath()
{
var candidates = new List<string>();
var envPath = Environment.GetEnvironmentVariable("DCIT_DOCTO_PATH");
if (!string.IsNullOrWhiteSpace(envPath))
{
candidates.Add(envPath);
}
candidates.Add(Path.Combine(_startupDirectory, "docto.exe"));
candidates.Add(Path.Combine(_startupDirectory, "tools", "DocTo", "docto.exe"));
foreach (var candidate in candidates)
{
if (!string.IsNullOrWhiteSpace(candidate) && File.Exists(candidate))
{
return candidate;
}
}
var pathEnv = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
foreach (var segment in pathEnv.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{
try
{
var candidate = Path.Combine(segment.Trim(), "docto.exe");
if (File.Exists(candidate))
{
return candidate;
}
}
catch
{
}
}
return null;
}
protected virtual bool CanWriteToDirectory(string directoryPath)
{
if (string.IsNullOrWhiteSpace(directoryPath))
{
return false;
}
try
{
Directory.CreateDirectory(directoryPath);
var probePath = Path.Combine(directoryPath, ".dcit-writecheck-" + Guid.NewGuid().ToString("N") + ".tmp");
File.WriteAllText(probePath, "probe");
File.Delete(probePath);
return true;
}
catch
{
return false;
}
}
private string ResolveAutomationProgId()
{
foreach (var progId in GetOfficeAutomationProgIds())
{
if (IsProgIdRegistered(progId))
{
return progId;
}
}
return null;
}
}
}