442 lines
22 KiB
VB.net
442 lines
22 KiB
VB.net
' =============================================================================
|
|
' NX Journal: 按需生成服务 worker (二期 A 版, NX 2506 实测适配版, 2026-08-27)
|
|
'
|
|
' ▍干什么: 常驻轮询 GenServer 任务队列, 认领任务后在**同一 NX 会话内**逐项生成:
|
|
' 开母模副本 → 设表达式 → 更新 → Save 副本 → PRT SaveAs →
|
|
' CloseAll 释放句柄 → 外部独立翻译器导出 STEP/IGES → 关闭不保存。
|
|
' 结果写 jobs\job_<id>.done (行式键值格式, 无 JSON — NX journal 编译环境没有 JSON 库)。
|
|
'
|
|
' ▍关键改造 (2026-08-27): 批处理内 DexManager 导出判 0 solid (ST-DEVELOPER 翻译器
|
|
' 在 run_journal 无 GUI 下读不到几何), 改为 Save 副本后 spawn 独立命令行翻译器
|
|
' step214ug.exe (.prt→.step) / iges.exe (.prt→.igs), 实测成功。
|
|
'
|
|
' ▍任务文件格式 (GenServer 写入, 本脚本解析; 母模/映射/开关/导出配置全部烘进任务, 不读 masters.json):
|
|
' ITEM
|
|
' SERIES=KC
|
|
' CODE=KC0032-87
|
|
' PARAM type=00 (每参数一行, 值可为空)
|
|
' PARAM bore=32
|
|
' MASTER=KC_master.prt
|
|
' MAP bore=bore (目录参数代码=NX表达式名)
|
|
' SW magnet,=magOn,0 (参数代码,参数值=NX表达式名,表达式值)
|
|
' EXP step=1 (导出格式开关; step 恒 1)
|
|
' END
|
|
'
|
|
' ▍运行 (run_journal 只接受一个参数; 用 WorkingDirectory 定位配置):
|
|
' WorkingDirectory = GenServer 运行目录 (含 worker-config.txt + worker-no.txt)
|
|
' run_journal.exe <本文件完整路径>
|
|
'
|
|
' ▍注意
|
|
' - 中文注释需 UTF-8 带 BOM (改完手动恢复 BOM)
|
|
' - 母模副本现在必须 Save (独立翻译器从磁盘读); 但副本用完即删, 绝不保留脏副本
|
|
' - 导出格式 (masters.json exports): step 恒导出, iges/prt 可选, parasolid/stl 已按用户要求砍掉
|
|
' - NX 2506 关键 API (反射探针核对): OpenBaseDisplay(批处理必须, OpenBase 后 Work=NULL) /
|
|
' ExpressionCollection.CreateExpression("Number","名=值") / UF EditExp(仅编辑已存在) / CloseAll 两参数
|
|
' =============================================================================
|
|
Option Strict Off
|
|
Imports System
|
|
Imports System.IO
|
|
Imports System.Text
|
|
Imports System.Diagnostics
|
|
Imports System.Collections.Generic
|
|
Imports NXOpen
|
|
Imports NXOpen.UF
|
|
|
|
Module WorkerGen
|
|
|
|
Dim theSession As Session = Session.GetSession()
|
|
Dim lw As ListingWindow = theSession.ListingWindow
|
|
|
|
Dim jobsDir, outputDir, mastersDir, workDir, nxBin As String
|
|
Dim workerNo As String = "0"
|
|
Dim pollMs As Integer = 1500
|
|
|
|
Sub Main()
|
|
lw.Open()
|
|
' 配置 = 当前工作目录 worker-config.txt (key=value 行式)
|
|
Dim cfgPath As String = Path.Combine(Directory.GetCurrentDirectory(), "worker-config.txt")
|
|
If Not File.Exists(cfgPath) Then
|
|
lw.WriteLine("[worker] 未找到配置: " & cfgPath & " (请以 GenServer 运行目录为工作目录启动)")
|
|
Return
|
|
End If
|
|
For Each line As String In File.ReadAllLines(cfgPath, Encoding.UTF8)
|
|
Dim i As Integer = line.IndexOf("="c)
|
|
If i <= 0 Then Continue For
|
|
Dim k As String = line.Substring(0, i).Trim()
|
|
Dim v As String = line.Substring(i + 1).Trim()
|
|
If k = "jobsDir" Then jobsDir = v
|
|
If k = "outputDir" Then outputDir = v
|
|
If k = "mastersDir" Then mastersDir = v
|
|
If k = "workDir" Then workDir = v
|
|
If k = "nxBin" Then nxBin = v
|
|
Next
|
|
If jobsDir.Length = 0 OrElse outputDir.Length = 0 Then
|
|
lw.WriteLine("[worker] 配置缺少 jobsDir/outputDir")
|
|
Return
|
|
End If
|
|
If nxBin.Length = 0 Then
|
|
' 回退: 自动探测 NX 安装目录 (部署到新机器无需手填)
|
|
For Each root As String In New String() {
|
|
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Siemens"),
|
|
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Siemens"),
|
|
"C:\Program Files\Siemens"}
|
|
If Not Directory.Exists(root) Then Continue For
|
|
For Each ver As String In Directory.GetDirectories(root, "NX*")
|
|
Dim b As String = Path.Combine(ver, "NXBIN")
|
|
If File.Exists(Path.Combine(b, "run_journal.exe")) Then nxBin = b : Exit For
|
|
Next
|
|
If nxBin.Length > 0 Then Exit For
|
|
Next
|
|
End If
|
|
If nxBin.Length = 0 Then
|
|
lw.WriteLine("[worker] 警告: 未找到 NX NXBIN 目录 (nxBin 未配置且自动探测失败), STEP/IGES 导出将失败")
|
|
Else
|
|
lw.WriteLine("[worker] nxBin=" & nxBin)
|
|
End If
|
|
Dim noPath As String = Path.Combine(Directory.GetCurrentDirectory(), "worker-no.txt")
|
|
If File.Exists(noPath) Then
|
|
Dim noTxt As String = File.ReadAllText(noPath, Encoding.UTF8).Trim()
|
|
If noTxt.Length > 0 Then workerNo = noTxt
|
|
End If
|
|
For Each d As String In {jobsDir, outputDir, workDir}
|
|
If d.Length > 0 AndAlso Not Directory.Exists(d) Then Directory.CreateDirectory(d)
|
|
Next
|
|
lw.WriteLine("[worker" & workerNo & "] 启动: jobs=" & jobsDir & " 输出=" & outputDir)
|
|
|
|
While True
|
|
Try
|
|
TouchHeartbeat()
|
|
ProcessNextJob()
|
|
Catch ex As Exception
|
|
lw.WriteLine("[worker" & workerNo & "] 循环异常: " & ex.Message)
|
|
End Try
|
|
Threading.Thread.Sleep(pollMs)
|
|
End While
|
|
End Sub
|
|
|
|
' ---- 认领一个任务并处理 (原子改名防双 worker 抢同一任务) ----
|
|
Sub ProcessNextJob()
|
|
Dim jobFile As String = Nothing
|
|
Dim files() As String = Directory.GetFiles(jobsDir, "job_*.json")
|
|
If files.Length = 0 Then Return
|
|
Array.Sort(files)
|
|
For Each f As String In files
|
|
Dim running As String = f.Substring(0, f.Length - 5) & ".running"
|
|
Try
|
|
File.Move(f, running)
|
|
jobFile = running
|
|
Exit For
|
|
Catch
|
|
' 被其他 worker 抢走, 试下一个
|
|
End Try
|
|
Next
|
|
If jobFile Is Nothing Then Return
|
|
|
|
Dim jobId As String = Path.GetFileName(jobFile).Replace("job_", "").Replace(".running", "")
|
|
Dim workJobDir As String = Path.Combine(workDir, "job_" & jobId)
|
|
Directory.CreateDirectory(workJobDir)
|
|
lw.WriteLine("[worker" & workerNo & "] 认领任务 " & jobId & " " & DateTime.Now.ToString("HH:mm:ss"))
|
|
|
|
Dim okOverall As Boolean = True
|
|
Dim errOverall As String = ""
|
|
Dim doneSb As New StringBuilder()
|
|
Dim items As New List(Of Dictionary(Of String, Object))()
|
|
Dim masterCopies As New Dictionary(Of String, String)() ' 同系列共用一份母模副本 (副本从不保存)
|
|
|
|
Try
|
|
items = ParseJob(File.ReadAllText(jobFile, Encoding.UTF8))
|
|
doneSb.AppendLine("OK=1")
|
|
doneSb.AppendLine("ERROR=")
|
|
For idx As Integer = 0 To items.Count - 1
|
|
Dim it As Dictionary(Of String, Object) = items(idx)
|
|
Dim series As String = GetStr(it, "series")
|
|
Dim code As String = GetStr(it, "code")
|
|
Dim pars As Dictionary(Of String, Object) = GetDict(it, "params")
|
|
Dim outDir As String = Path.Combine(outputDir, series, code)
|
|
Directory.CreateDirectory(outDir)
|
|
Dim itemOk As Boolean = True
|
|
Dim itemErr As String = ""
|
|
Dim itemHit As Boolean = False
|
|
Dim filesList As New List(Of String)()
|
|
Try
|
|
' 检索先行 (认领时再查一次, 防并发窗口重复生成)
|
|
If OutputHit(series, code, it) Then
|
|
itemHit = True
|
|
filesList = ListOutputFiles(code, it)
|
|
lw.WriteLine(" [" & code & "] 已存在, 命中复用")
|
|
Else
|
|
' 拷母模副本 (同系列共用; 绝不保存)
|
|
If Not masterCopies.ContainsKey(series) Then
|
|
Dim src As String = Path.Combine(mastersDir, series, GetStr(it, "master"))
|
|
If Not File.Exists(src) Then Throw New Exception("母模缺失: " & src)
|
|
Dim dst As String = Path.Combine(workJobDir, series & "_master.prt")
|
|
File.Copy(src, dst, True)
|
|
' 清只读属性 (源母模可能带只读, NX 只读打开会拒绝保存/导出)
|
|
File.SetAttributes(dst, File.GetAttributes(dst) And Not FileAttributes.ReadOnly)
|
|
masterCopies(series) = dst
|
|
End If
|
|
GenerateOne(series, code, pars, it, masterCopies(series), outDir)
|
|
filesList = ListOutputFiles(code, it)
|
|
lw.WriteLine(" [" & code & "] 生成完成 → " & outDir)
|
|
End If
|
|
Catch ex As Exception
|
|
okOverall = False
|
|
itemOk = False
|
|
itemErr = ex.Message
|
|
lw.WriteLine(" [" & code & "] 失败: " & ex.Message)
|
|
End Try
|
|
doneSb.AppendLine("ITEM")
|
|
doneSb.AppendLine("SERIES=" & series)
|
|
doneSb.AppendLine("CODE=" & code)
|
|
doneSb.AppendLine("OK=" & (If(itemOk, "1", "0")))
|
|
doneSb.AppendLine("HIT=" & (If(itemHit, "1", "0")))
|
|
doneSb.AppendLine("ERROR=" & itemErr)
|
|
For Each f As String In filesList
|
|
doneSb.AppendLine("FILE=" & f)
|
|
Next
|
|
doneSb.AppendLine("END")
|
|
' 逐项进度 (批量打包 UI 显示 done/total)
|
|
File.WriteAllText(Path.Combine(jobsDir, "job_" & jobId & ".prog"),
|
|
"DONE=" & (idx + 1) & vbCrLf & "TOTAL=" & items.Count & vbCrLf, Encoding.UTF8)
|
|
' 关闭所有部件 (不保存), 会话内循环 (NX 2506: CloseAll 两参数)
|
|
Try
|
|
theSession.Parts.CloseAll(NXOpen.BasePart.CloseModified.CloseModified, Nothing)
|
|
Catch
|
|
End Try
|
|
Next
|
|
Catch ex As Exception
|
|
okOverall = False
|
|
errOverall = ex.Message
|
|
lw.WriteLine("[worker" & workerNo & "] 任务异常: " & ex.Message)
|
|
End Try
|
|
|
|
' 写结果 (原子: 先写临时再改名; 错误信息去换行防格式破坏)
|
|
Dim doneText As String = doneSb.ToString()
|
|
If Not okOverall Then
|
|
Dim errClean As String = errOverall.Replace(vbCr, " ").Replace(vbLf, " ")
|
|
If doneText.IndexOf("ITEM", StringComparison.OrdinalIgnoreCase) < 0 Then
|
|
doneText = "OK=0" & vbCrLf & "ERROR=" & errClean & vbCrLf
|
|
Else
|
|
doneText = doneText.Replace("OK=1" & vbCrLf & "ERROR=", "OK=0" & vbCrLf & "ERROR=" & errClean)
|
|
End If
|
|
End If
|
|
Dim donePath As String = Path.Combine(jobsDir, "job_" & jobId & ".done")
|
|
Dim tmpPath As String = donePath & ".tmp"
|
|
File.WriteAllText(tmpPath, doneText, New UTF8Encoding(True))
|
|
If File.Exists(donePath) Then File.Delete(donePath)
|
|
File.Move(tmpPath, donePath)
|
|
Try
|
|
File.Delete(jobFile) ' 删 .running
|
|
Directory.Delete(workJobDir, True) ' 任务私有工作副本即清 (输出留存不删)
|
|
Catch
|
|
End Try
|
|
lw.WriteLine("[worker" & workerNo & "] 任务 " & jobId & " 结束 " & (If(okOverall, "OK", "FAIL")))
|
|
End Sub
|
|
|
|
' ---- 任务文件解析 (行式键值; 返回每项一个字典: series/code/params/master/map/sw/exp) ----
|
|
Function ParseJob(text As String) As List(Of Dictionary(Of String, Object))
|
|
Dim result As New List(Of Dictionary(Of String, Object))()
|
|
Dim cur As Dictionary(Of String, Object) = Nothing
|
|
For Each raw As String In text.Split(New String() {vbCrLf, vbLf, vbCr}, StringSplitOptions.None)
|
|
Dim l As String = raw.Trim()
|
|
If l.Length = 0 Then Continue For
|
|
If l = "ITEM" Then
|
|
cur = New Dictionary(Of String, Object)()
|
|
cur("params") = New Dictionary(Of String, Object)()
|
|
cur("map") = New Dictionary(Of String, Object)()
|
|
cur("sw") = New List(Of Object)()
|
|
cur("exp") = New Dictionary(Of String, Object)()
|
|
result.Add(cur)
|
|
Continue For
|
|
End If
|
|
If l = "END" Then cur = Nothing : Continue For
|
|
If cur Is Nothing Then Continue For
|
|
If l.StartsWith("SERIES=") Then cur("series") = l.Substring(7).Trim() : Continue For
|
|
If l.StartsWith("CODE=") Then cur("code") = l.Substring(5).Trim() : Continue For
|
|
If l.StartsWith("MASTER=") Then cur("master") = l.Substring(7).Trim() : Continue For
|
|
If l.StartsWith("PARAM ") Then
|
|
Dim rest As String = l.Substring(6)
|
|
Dim j As Integer = rest.IndexOf("="c)
|
|
If j > 0 Then CType(cur("params"), Dictionary(Of String, Object))(rest.Substring(0, j).Trim()) = rest.Substring(j + 1).Trim()
|
|
Continue For
|
|
End If
|
|
If l.StartsWith("MAP ") Then
|
|
Dim rest As String = l.Substring(4)
|
|
Dim j As Integer = rest.IndexOf("="c)
|
|
If j > 0 Then CType(cur("map"), Dictionary(Of String, Object))(rest.Substring(0, j).Trim()) = rest.Substring(j + 1).Trim()
|
|
Continue For
|
|
End If
|
|
If l.StartsWith("SW ") Then
|
|
' SW 参数代码,参数值=表达式名,表达式值
|
|
Dim rest As String = l.Substring(3)
|
|
Dim j As Integer = rest.IndexOf("="c)
|
|
If j > 0 Then
|
|
Dim left() As String = rest.Substring(0, j).Split(","c)
|
|
Dim right() As String = rest.Substring(j + 1).Split(","c)
|
|
If left.Length >= 2 AndAlso right.Length >= 2 Then
|
|
Dim sw As New Dictionary(Of String, Object)()
|
|
sw("pc") = left(0).Trim() : sw("pv") = left(1).Trim()
|
|
sw("ex") = right(0).Trim() : sw("ev") = right(1).Trim()
|
|
CType(cur("sw"), List(Of Object)).Add(sw)
|
|
End If
|
|
End If
|
|
Continue For
|
|
End If
|
|
If l.StartsWith("EXP ") Then
|
|
Dim rest As String = l.Substring(4)
|
|
Dim j As Integer = rest.IndexOf("="c)
|
|
If j > 0 AndAlso rest.Substring(j + 1).Trim() = "1" Then
|
|
CType(cur("exp"), Dictionary(Of String, Object))(rest.Substring(0, j).Trim()) = "1"
|
|
End If
|
|
Continue For
|
|
End If
|
|
Next
|
|
Return result
|
|
End Function
|
|
|
|
Function GetStr(d As Dictionary(Of String, Object), key As String) As String
|
|
If d Is Nothing OrElse Not d.ContainsKey(key) OrElse d(key) Is Nothing Then Return ""
|
|
Return Convert.ToString(d(key))
|
|
End Function
|
|
|
|
Function GetDict(d As Dictionary(Of String, Object), key As String) As Dictionary(Of String, Object)
|
|
If d Is Nothing OrElse Not d.ContainsKey(key) OrElse d(key) Is Nothing Then Return New Dictionary(Of String, Object)()
|
|
Return CType(d(key), Dictionary(Of String, Object))
|
|
End Function
|
|
|
|
' 导出格式开关: job 里 EXP 行 (EXP parasolid=1); step 恒导出
|
|
Function ExpOn(it As Dictionary(Of String, Object), fmt As String) As Boolean
|
|
If fmt = "step" Then Return True
|
|
Dim exp As Dictionary(Of String, Object) = GetDict(it, "exp")
|
|
Return exp.ContainsKey(fmt)
|
|
End Function
|
|
|
|
' ---- 检索先行: 输出目录存在且全部配置格式文件齐全 ----
|
|
Function OutputHit(series As String, code As String, it As Dictionary(Of String, Object)) As Boolean
|
|
Dim dir As String = Path.Combine(outputDir, series, code)
|
|
If Not Directory.Exists(dir) Then Return False
|
|
For Each f As String In New String() {code & ".stp", code & ".x_t", code & ".igs", code & ".stl", code & ".prt"}
|
|
If f.EndsWith(".stp") AndAlso Not File.Exists(Path.Combine(dir, f)) Then Return False
|
|
If f.EndsWith(".x_t") AndAlso ExpOn(it, "parasolid") AndAlso Not File.Exists(Path.Combine(dir, f)) Then Return False
|
|
If f.EndsWith(".igs") AndAlso ExpOn(it, "iges") AndAlso Not File.Exists(Path.Combine(dir, f)) Then Return False
|
|
If f.EndsWith(".stl") AndAlso ExpOn(it, "stl") AndAlso Not File.Exists(Path.Combine(dir, f)) Then Return False
|
|
If f.EndsWith(".prt") AndAlso ExpOn(it, "prt") AndAlso Not File.Exists(Path.Combine(dir, f)) Then Return False
|
|
Next
|
|
Return True
|
|
End Function
|
|
|
|
Function ListOutputFiles(code As String, it As Dictionary(Of String, Object)) As List(Of String)
|
|
Dim list As New List(Of String)()
|
|
list.Add(code & ".stp")
|
|
If ExpOn(it, "parasolid") Then list.Add(code & ".x_t")
|
|
If ExpOn(it, "iges") Then list.Add(code & ".igs")
|
|
If ExpOn(it, "stl") Then list.Add(code & ".stl")
|
|
If ExpOn(it, "prt") Then list.Add(code & ".prt")
|
|
Return list
|
|
End Function
|
|
|
|
' ---- 单型号生成: 开副本 → 设表达式 → 更新 → 多格式导出 → 关闭 ----
|
|
Sub GenerateOne(series As String, code As String, pars As Dictionary(Of String, Object),
|
|
it As Dictionary(Of String, Object), masterCopy As String, outDir As String)
|
|
' 1) 打开母模副本 (OpenBaseDisplay 使其成为工作部件; 副本会 Save 供外部翻译器读盘, 用完即删)
|
|
Dim partLoadStatus1 As NXOpen.PartLoadStatus = Nothing
|
|
Dim basePart1 As NXOpen.BasePart = theSession.Parts.OpenBaseDisplay(masterCopy, partLoadStatus1)
|
|
If partLoadStatus1 IsNot Nothing Then partLoadStatus1.Dispose()
|
|
Dim workPart As NXOpen.Part = theSession.Parts.Work
|
|
If workPart Is Nothing Then Throw New Exception("打开母模失败: " & masterCopy)
|
|
|
|
' 2) 设表达式 (UF EditExp 只编辑已存在的表达式; 母模必须已建好这些表达式)
|
|
Dim ufsW As UFSession = UFSession.GetUFSession()
|
|
Dim exprMap As Dictionary(Of String, Object) = GetDict(it, "map")
|
|
For Each kv As KeyValuePair(Of String, Object) In exprMap
|
|
If pars.ContainsKey(kv.Key) Then
|
|
ufsW.Modl.EditExp(Convert.ToString(kv.Value) & "=" & ValueStr(pars(kv.Key)))
|
|
End If
|
|
Next
|
|
Dim swList As Object = Nothing
|
|
If it.ContainsKey("sw") Then swList = it("sw")
|
|
If swList IsNot Nothing Then
|
|
For Each swObj As Object In CType(swList, List(Of Object))
|
|
Dim sw As Dictionary(Of String, Object) = CType(swObj, Dictionary(Of String, Object))
|
|
If pars.ContainsKey(GetStr(sw, "pc")) AndAlso ValueStr(pars(GetStr(sw, "pc"))) = GetStr(sw, "pv") Then
|
|
ufsW.Modl.EditExp(GetStr(sw, "ex") & "=" & GetStr(sw, "ev"))
|
|
End If
|
|
Next
|
|
End If
|
|
|
|
' 3) Update model
|
|
ufsW.Modl.Update()
|
|
|
|
' 4) Save the copy to disk so independent translators can read it.
|
|
' (in-session DexManager export yields 0 solids in batch - verified; see dev log 4.5)
|
|
Dim pssSave As NXOpen.PartSaveStatus = workPart.Save(NXOpen.BasePart.SaveComponents.True, NXOpen.BasePart.CloseAfterSave.False)
|
|
If pssSave IsNot Nothing Then pssSave.Dispose()
|
|
|
|
' 5) PRT save-as (NX native parametric part; session SaveAs)
|
|
If ExpOn(it, "prt") Then ExportPrt(Path.Combine(outDir, code & ".prt"))
|
|
|
|
' 6) Close all parts to release the file handle so external translators can read
|
|
Try
|
|
theSession.Parts.CloseAll(NXOpen.BasePart.CloseModified.CloseModified, Nothing)
|
|
Catch
|
|
End Try
|
|
|
|
' 7) Export via independent CLI translators (bypass batch 0-solid dead end)
|
|
ExportStepCli(masterCopy, Path.Combine(outDir, code & ".stp"))
|
|
If ExpOn(it, "iges") Then ExportIgesCli(masterCopy, Path.Combine(outDir, code & ".igs"))
|
|
End Sub
|
|
|
|
' ---- Independent CLI translators (bypass batch 0-solid dead end) ----
|
|
' step214ug.exe: bidirectional. input .prt -> export STEP. (verified 2 solids, 7KB)
|
|
' Syntax: step214ug.exe <input> o=<output> d=<def> l=<log>
|
|
Sub ExportStepCli(inputPrt As String, fileName As String)
|
|
If File.Exists(fileName) Then File.Delete(fileName)
|
|
Dim psi As New ProcessStartInfo()
|
|
psi.FileName = Path.Combine(nxBin, "step214ug.exe")
|
|
psi.Arguments = """" & inputPrt & """ o=""" & fileName & """ l=""" & fileName & ".log"""
|
|
psi.WorkingDirectory = Path.GetDirectoryName(inputPrt)
|
|
psi.UseShellExecute = False
|
|
psi.CreateNoWindow = True
|
|
Dim p As Process = Process.Start(psi)
|
|
p.WaitForExit()
|
|
If Not File.Exists(fileName) OrElse (New FileInfo(fileName)).Length < 1000 Then
|
|
Throw New Exception("STEP export failed (empty/missing): " & fileName)
|
|
End If
|
|
End Sub
|
|
|
|
' iges.exe: input .prt -> export IGES. (verified Face=6)
|
|
' Syntax: iges.exe <input> o=<output> l=<log>
|
|
Sub ExportIgesCli(inputPrt As String, fileName As String)
|
|
If File.Exists(fileName) Then File.Delete(fileName)
|
|
Dim psi As New ProcessStartInfo()
|
|
psi.FileName = Path.Combine(nxBin, "iges.exe")
|
|
psi.Arguments = """" & inputPrt & """ o=""" & fileName & """ l=""" & fileName & ".log"""
|
|
psi.WorkingDirectory = Path.GetDirectoryName(inputPrt)
|
|
psi.UseShellExecute = False
|
|
psi.CreateNoWindow = True
|
|
Dim p As Process = Process.Start(psi)
|
|
p.WaitForExit()
|
|
If Not File.Exists(fileName) Then
|
|
Throw New Exception("IGES export failed (missing): " & fileName)
|
|
End If
|
|
End Sub
|
|
|
|
' NX native part export: save-as current work part (parametric exprs + feature tree; 2026-08-26 user request)
|
|
Sub ExportPrt(fileName As String)
|
|
Dim pss As NXOpen.PartSaveStatus = theSession.Parts.Work.SaveAs(fileName)
|
|
If pss IsNot Nothing Then pss.Dispose()
|
|
End Sub
|
|
|
|
' ---- 工具 ----
|
|
Function ValueStr(v As Object) As String
|
|
If v Is Nothing Then Return ""
|
|
Return Convert.ToString(v, System.Globalization.CultureInfo.InvariantCulture).Replace(",", ".")
|
|
End Function
|
|
|
|
Sub TouchHeartbeat()
|
|
Dim hb As String = Path.Combine(workDir, "heartbeat_" & workerNo & ".txt")
|
|
File.WriteAllText(hb, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), New UTF8Encoding(True))
|
|
End Sub
|
|
|
|
End Module
|