2. NX Open与.NET集成

NX Open 是 Siemens NX 对外提供的二次开发接口体系,它并不是单一的一套 API,而是由多个层次、多种语言绑定共同组成的开发平台。对于使用 C# 或 VB.NET 的开发者来说,NX Open 通过 .NET 程序集的形式暴露接口,核心程序集包括 NXOpen.dll、NXOpen.UF.dll、NXOpen.Utilities.dll 等。理解这些程序集的职责划分、引用方式以及命名空间的组织逻辑,是搭建一个可编译、可调试、可部署的 NX 二次开发项目的第一步。

一、.NET 项目类型与目标框架选择

NX Open 的 .NET 程序集是面向 .NET Framework 编译的,因此在创建项目时,应选择“类库(.NET Framework)”模板,而不是 .NET Core 或 .NET 5/6/7/8 的类库模板。目标框架需要与所安装 NX 版本匹配:NX 12 及更早版本通常使用 .NET Framework 4.6 或 4.6.1;NX 1847 至 NX 2007 系列一般使用 .NET Framework 4.8;较新的 NX 版本仍以 .NET Framework 4.8 为主。若目标框架选错,编译时可能通过,但加载到 NX 进程中会因运行时版本不匹配而失败。

项目输出类型应为“类库”,输出路径建议指向 NX 的 UGII 目录下的自定义子目录,或指向一个独立的开发目录,再通过环境变量 UGII_USER_DIR 或 UGII_SITE_DIR 让 NX 识别。对于调试阶段,更推荐将生成目录直接设置为 NX 的 UGII\managed 或自定义的 application 目录,这样在 NX 中通过“文件—执行—NX Open”即可直接调用。

二、引用管理:必须引用的程序集与“复制本地”设置

一个典型的 NX Open .NET 项目至少需要引用以下程序集:

  • NXOpen.dll:面向对象的高层 API,包含 NXOpen.Session、NXOpen.Part、NXOpen.Features、NXOpen.UI 等命名空间,是日常开发中使用频率最高的程序集。
  • NXOpen.UF.dll:对传统 User Function(UF)函数的 .NET 封装,命名空间为 NXOpen.UF,内部类名通常以 UF 开头,如 UFModl、UFSf、UFUi 等。
  • NXOpen.Utilities.dll:提供 NXOpen.Utilities 命名空间下的辅助类型,如 NXOpen.Utilities.NXObjectManager、TaggedObject 与 Tag 之间的转换等。

这些程序集位于 NX 安装目录的 NXBIN\managed 文件夹下。在 Visual Studio 中添加引用时,应通过“浏览”定位到该目录,而不是从 GAC 或 NuGet 获取。关键设置是:将上述程序集的“复制本地(Copy Local)”属性设为 False。原因是这些 DLL 在 NX 进程启动时已经由 NX 自身加载,如果项目输出目录中再复制一份,可能导致版本冲突或类型加载异常。对于自己编写的辅助类库,则可以正常复制本地。

如果需要在未安装 NX 的机器上编译,可以把 NXBIN\managed 下的 DLL 复制到开发机的固定目录,并在项目中以该目录作为引用路径;但运行时仍必须由 NX 进程提供这些程序集。

三、NXOpen.dll 与 NXOpen.UF.dll 的命名空间解析

NXOpen.dll 采用面向对象的设计,其命名空间按功能域划分。最核心的是 NXOpen 根命名空间,其中 Session 类是整个 API 的入口,通过 Session.GetSession() 获取当前会话;Part 类代表部件文件;TaggedObject 是所有可持久化对象的基类。在此基础上,NXOpen.Features 提供特征创建与编辑能力,NXOpen.Assemblies 处理装配,NXOpen.Drawings 处理制图,NXOpen.CAM 处理加工,NXOpen.UI 提供界面交互,NXOpen.Selection 负责选择操作。

NXOpen.UF.dll 则是对传统 C 语言 UF 函数的封装,命名空间统一为 NXOpen.UF。它并不追求面向对象的优雅,而是尽量保持与 C 函数的一一对应关系。例如 C 函数 UF_MODL_create_block1 对应 .NET 中的 UFModl.CreateBlock1。每个功能域对应一个类:UFModl 对应建模,UFSf 对应曲面,UFUi 对应界面,UFAssem 对应装配,UFDisp 对应显示。这些类通常通过 UFSession.GetUFSession() 获取实例。

两者的关系可以这样理解:NXOpen.dll 是“新式高层接口”,封装更完整、类型更安全、更符合 .NET 编程习惯;NXOpen.UF.dll 是“传统底层接口”,覆盖范围更广,某些功能在高层 API 中尚未提供,只能通过 UF 函数实现。实际开发中,常见做法是以 NXOpen 为主,在遇到高層 API 无法完成的操作时,再调用 NXOpen.UF 补充。

NX Open .NET 程序集与命名空间结构 NX 进程 (ugs_router / nx.exe) NXOpen.dll(高层面向对象 API) NXOpen Session · Part · TaggedObject NXOpen.Features 特征创建与编辑 NXOpen.Assemblies / Drawings / CAM 装配 · 制图 · 加工 NXOpen.UI / Selection 界面交互 · 选择操作 NXOpen.UF.dll(传统 UF 封装) NXOpen.UF UFSession.GetUFSession() UFModl · UFSf · UFUi 建模 · 曲面 · 界面 UFAssem · UFDisp 装配 · 显示 与 C 函数一一对应 UF_MODL_create_block1 → UFModl.CreateBlock1 NXOpen.Utilities.dll(辅助工具) NXObjectManager · TaggedObject 与 Tag 转换 · 异常处理辅助 互补 引用设置:Copy Local = False(由 NX 进程提供程序集) 程序集路径:NXBIN\managed\ · 目标框架:.NET Framework 4.8(视 NX 版本而定)

四、最小可运行示例与关键代码结构

下面给出一个 C# 类库的最小结构,用于在 NX 中创建一个长方体并弹出提示。该示例同时使用了 NXOpen 和 NXOpen.UF,便于观察两者的调用差异。

using System;
using NXOpen;
using NXOpen.UF;

public class CreateBlockExample
{
    public static void Main(string[] args)
    {
        Session theSession = Session.GetSession();
        UFSession theUfSession = UFSession.GetUFSession();
        Part workPart = theSession.Parts.Work;

        // 使用 NXOpen 高层 API 创建长方体特征
        NXOpen.Features.BlockFeatureBuilder blockBuilder =
            workPart.Features.CreateBlockFeatureBuilder(null);

        NXOpen.Point3d origin = new NXOpen.Point3d(0.0, 0.0, 0.0);
        NXOpen.Vector3d orientation = new NXOpen.Vector3d(1.0, 0.0, 0.0);

        blockBuilder.SetOriginAndLengths(origin, "100", "60", "40");
        blockBuilder.SetOrientation(orientation);

        NXOpen.Features.Feature blockFeature = blockBuilder.CommitFeature();
        blockBuilder.Destroy();

        // 使用 NXOpen.UF 获取当前部件单位信息
        int units;
        theUfSession.Modl.AskPartUnits(out units);

        theUfSession.Ui.DisplayMessage(
            "长方体已创建,部件单位代码:" + units, 1);
    }

    public static int GetUnloadOption(string arg)
    {
        return (int)Session.LibraryUnloadOption.Immediately;
    }
}

这段代码中有几个关键点值得注意。第一,Session.GetSession() 和 UFSession.GetUFSession() 分别获取两套 API 的会话入口,二者可以共存。第二,workPart.Features.CreateBlockFeatureBuilder 是典型的 Builder 模式:先创建构建器,设置参数,再 CommitFeature() 提交,最后 Destroy() 释放。第三,theUfSession.Modl.AskPartUnits 展示了 UF 函数的调用方式,参数通过 out 返回。第四,GetUnloadOption 是 NX 识别 DLL 卸载策略的约定方法,返回 Immediately 表示调用结束后立即卸载,适合无状态工具;若需要保持静态变量或缓存,可返回 AtTermination。

五、常见配置错误与排查方向

在实际配置过程中,以下几类问题出现频率最高。第一类是“找不到类型或命名空间”,通常是因为没有正确引用 NXOpen.dll,或引用了错误版本的 DLL。第二类是“无法加载程序集”,多由 Copy Local 设置不当或目标框架不匹配引起。第三类是“方法签名不匹配”,常见于 UF 封装中 out 参数与 C 指针的对应关系理解错误。第四类是“NX 中看不到菜单或按钮”,这通常不是编译问题,而是 DLL 未放入 NX 可识别的搜索路径,或未正确配置 UGII_USER_DIR。

调试 NX Open .NET 程序时,不要试图用“附加到进程”之外的方式启动。正确做法是:先启动 NX,再在 Visual Studio 中通过“调试—附加到进程”选择 nx.exe,然后在 NX 中触发命令,断点才会命中。