c# - 获取Enterprise Architect包节点的所有子节点

标签 c# console-application com-interop enterprise-architect

我需要什么

步骤 1

我需要导出主根节点(=包)下的所有信息,无论节点类型如何。

步骤 2

使用该导出信息,我需要映射到第三方提供的 JSON 合约。

第 3 步

然后第三方可以使用我的 JSON 将信息从 EA 导入到他们的系统中。

我有什么

第 1 步已完成,我的目标位置上有一个基于文件的数据转储,如下所示:

enter image description here

基本上,这是一个静态 html 网站,通过在 TreeView 中显示信息来对应 EA 结构,类似于您在 EA 中看到的方式。

我能做什么

浏览 EARoot 文件夹并读取其中的 html 文件中提供的所有信息。

就我而言,EARoot 包含三个子文件夹:

  • EA1
  • EA2
  • EA3

其中 EA1 子文件夹包含

  • EA1
  • EA2
  • EA1.html
  • EA2.html
  • EA3.html

html 文件包含我需要的信息,可以以有意义的方式解释数据。

陷阱

是否没有直接链接到 EA 中的文件和实际节点结构。我可以根据可用数据做出假设,该假设在大多数情况下都有效,但它需要可靠且始终有效。

我可以在每个 html 文件中找到正确的 UUID,因此这将是链接到该结构的一种方法,但是要找到该结构,我需要能够获取节点的所有子节点的 UUID 并遍历递归地构建树。​​

我尝试了以下方法:

public Package GetRootPackage()
{
    using (var repo = EnterpriseArchitect.Repository.Open(_connectionString))
    {
        return repo.GetPackage(this.RootPackageName);
    }
}

EnterpriseArchitect.Repository 是 EA.Repository 之上的包装器,使其成为 IDisposable 以实现更好的连接管理。

使用上面定义的 GetRootPackage 方法,我可以连接并加载我想要的节点:

var root = MyBuilder.ConnectTo(myConnectionString)
    .RootPackage(rootNodeName)
    .GetRootPackage();

我想我就可以像这样获取它的 child :

var children = root.Packages;

但是后来我得到了这个令人讨厌的错误:

System.Runtime.InteropServices.COMException HResult=0x80010105
Message=The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT)) Source=my.console
StackTrace: at EA.IDualPackage.get_Elements() at my.console.Program.Main(String[] args) in C:\Repos\my.console\Program.cs:line 29

我检查了事件查看器以获取更多信息,并发现(仅)这个:

Faulting application name: EA.exe, version: 14.1.0.1427, time stamp: 0x5b9718a5
Faulting module name: EA.exe, version: 14.1.0.1427, time stamp: 0x5b9718a5
Exception code: 0xc0000005
Fault offset: 0x0049ffc4
Faulting process id: 0x2eac
Faulting application start time: 0x01d56eb6d931a965
Faulting application path: C:\Program Files (x86)\Sparx Systems\EA\EA.exe
Faulting module path: C:\Program Files (x86)\Sparx Systems\EA\EA.exe
Report Id: 223f8c89-c84a-45c6-9100-82af8e94643a
Faulting package full name: 
Faulting package-relative application ID: 

问题

我发现关于此 HResult=0x80010105 的内容似乎与 Excel 相关,因此我不确定这是否有意义。

我从控制台运行,因为我知道 interop.EA 应该被认为是非线程安全的。

What can I do to avoid this issue and get the child packages?

最佳答案

这是 EA.Repository 之上的 IDisposable 包装器导致了问题。如果我直接调用存储库(使用 try catch finally 而不是 IDisposable),我就能够获取子节点。

防御性编程就这么多了......


而不是我的包装:

public class Repository : IDisposable
{
    private EA.Repository _repo;

    protected Repository(string connectionString)
    {
        _repo = new EA.Repository();
        _repo.OpenFile(connectionString);
    }

    ...

    public void Dispose()
    {
        _repo.CloseFile();
        _repo = null;
    }
}

我现在直接使用 EA 存储库来获取(根)包信息:

public Package GetRootPackage()
{
    var repo = new EA.Repository();

    try
    {    
        repo.OpenFile(_connectionString);

        var pkg = (EA.Package)repo.Models.GetByName(this.RootPackageName);

        if (pkg is null)
            throw new ApplicationException($"Package \"{this.RootPackageName}\" not found.");

        return pkg;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        throw;
    }
    finally
    {
        Console.WriteLine("Closing repository...");
        repo.CloseFile();
    }
}

通过这个我可以做到:

var root = MyBuilder.ConnectTo(myConnectionString)
    .RootPackage(rootNodeName)
    .GetRootPackage();

foreach (var item in root.Packages)
{
    var child = (IDualPackage)item;    
    var guid = child.PackageGUID;
}

并且 guid var 包含正确的 PackageGUID

关于c# - 获取Enterprise Architect包节点的所有子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58005654/

相关文章:

C# 如何将 CallNtPowerInformation 与 Interop 结合使用以获取 SYSTEM_POWER_INFORMATION

c# - 每个配置文件只允许一个 configSections 元素,如果存在,则必须是根配置元素的第一个子元素

vb.net - 通过互操作在 VB6 中使用 VB.NET 类需要类具有构造函数吗?

c# - 在 C# 中使用 SOAP API 调用无需代理的 Web 服务

c# - 如何过滤字典以包含具有唯一值的项目?

c# - 不同服务器上的相同数据库

c++ - 使用 kbhit() 暂停终端输出?

c# - 具有无限循环和 thread.sleep 高 CPU 使用率的多线程

c# - 是否可以通过 COM 互操作转发委托(delegate)?

c# - 当 "Class not registered"时,实例化 COM 组件失败并显示 "Run As Administrator"