143 lines
4.5 KiB
C#
143 lines
4.5 KiB
C#
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;
|
||
}
|
||
}
|
||
} |