Files
DCIT/DCIT.Core/Services/RuntimeEnvironmentValidationService.cs

143 lines
4.5 KiB
C#
Raw Normal View History

2026-07-13 10:04:36 +08:00
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;
}
}
}