P.S.: Так мой код у тебя заработал или нет?
Увы, но не заработал.
Можешь выложить здесь. Если понадобится - я перенесу.
Итак, предупреждаю, решение не является оптимальным:
1. С помощью AcCoreConsole.exe (AutoCAD 2014) и скрипта start.scr я получаю dxf-файл.
start.scr выглядит так:
_filedia
0
_dxfout
"C:\Users\PASHIN~1\AppData\Local\Temp\DWG2PDF22032017172702888554\start.dxf"
16
_filedia
1
2. Парсим dxf-файл с помощью регулярных выражений и определяем листы с их настройками принтера. В моём случае я ограничился поиском тех листов, у которых имя принтера «DWG_To_PDF_Gallurgy.pc3». Для этого я создал свой класс, в который складывал имена принтеров, имена листов и форматы принтера. Затем я отсеял ненужные мне листы:
Как я парсил DXF-файл:
Public Sub Read_DXF_And_Generate_DSD(ByVal OriginalDWG As String, ByVal DXFPath As String, ByVal DSDPath As String)
Dim DXF As String
DXF
= IO.
File.
ReadAllText(DXFPath
)
Dim DSD As New acDsdData
Dim regexp As New Regex("AcDbPlotSettings(.*?)• 71")
Dim regexpName As New Regex("• 2(.*?)• 4")
Dim regexpFormat As New Regex("• 4(.*?)• 6")
Dim regexpLayout As New Regex("•AcDbLayout(.*?)• 70")
Dim PrinterName As String
Dim PrinterFormat As String
Dim LayoutName As String
Dim i As Integer
Dim m As MatchCollection
DXF = DXF.Replace(Chr(10), "•")
m = regexp.Matches(DXF)
For i = 0 To m.Count - 1
Dim mm As MatchCollection
mm = regexpName.Matches(m.Item(i).Value)
Try
PrinterName = (mm.Item(0).Value)
PrinterName = PrinterName.Replace("• 2", "")
PrinterName = PrinterName.Replace("• 4", "")
PrinterName = PrinterName.Replace(Chr(13), "")
PrinterName = PrinterName.Replace("•", "")
Dim mmm As MatchCollection
mmm = regexpFormat.Matches(m.Item(i).Value)
PrinterFormat = (mmm.Item(0).Value)
PrinterFormat = PrinterFormat.Replace("• 4", "")
PrinterFormat = PrinterFormat.Replace("• 6", "")
PrinterFormat = PrinterFormat.Replace(Chr(13), "")
PrinterFormat = PrinterFormat.Replace("•", "")
Dim mmmm As MatchCollection
mmmm = regexpLayout.Matches(m.Item(i).Value)
LayoutName = (mmmm.Item(0).Value)
LayoutName = LayoutName.Replace("•AcDbLayout", "")
LayoutName = LayoutName.Replace("• 1", "")
LayoutName = LayoutName.Replace("• 70", "")
LayoutName = LayoutName.Replace(Chr(13), "")
LayoutName = LayoutName.Replace("•", "")
Dim DSDL As New acLayoutInfo
DSDL.PrinterFormat = PrinterFormat
DSDL.PrinterName = PrinterName
DSDL.LayoutName = LayoutName
DSD.Layouts.Add(DSDL)
Catch ex As Exception
MsgBox(ex.Message)
End Try
Next
StartHerePlease:
For Each DSDL As acLayoutInfo In DSD.Layouts
If DSDL.LayoutName.Trim = "Model" Then
DSD.Layouts.Remove(DSDL)
GoTo StartHerePlease
End If
If DSDL.LayoutName.Trim = "Модель" Then
DSD.Layouts.Remove(DSDL)
GoTo StartHerePlease
End If
If DSDL.LayoutName.Trim = "Элементы оформления" Then
DSD.Layouts.Remove(DSDL)
GoTo StartHerePlease
End If
If DSDL.PrinterName <> "DWG_To_PDF_Gallurgy.pc3" Then
DSD.Layouts.Remove(DSDL)
GoTo StartHerePlease
End If
Next
Make_DSD_File(OriginalDWG, DSDPath, DSD)
End Sub
Как я генерировал DSD-файл:
Public Function Make_DSD_File(ByVal OriginalDWG As String, ByVal PathName As String, ByRef DSD As acDsdData) As Boolean
Make_DSD_File = False
Dim DsdFile As New List(Of String)
If DSD.Layouts.Count > 0 Then
' Создаем DSD-файл
With DsdFile
.Add("[DWF6Version]")
.Add("Ver=1")
.Add("[DWF6MinorVersion]")
.Add("MinorVer=1")
For Each DSDL As acLayoutInfo In DSD.Layouts
If DSDL.LayoutName.Trim = "Model" Then
ElseIf DSDL.LayoutName.Trim = "Модель" Then
ElseIf DSDL.LayoutName.Trim = "Элементы оформления" Then
Else
If DSDL.PrinterName = "DWG_To_PDF_Gallurgy.pc3" Then
.Add("[DWF6Sheet:" & IO.Path.GetFileNameWithoutExtension(OriginalDWG) & "-" & DSDL.LayoutName & "]")
.Add("DWG=" & OriginalDWG)
.Add("Layout=" & DSDL.LayoutName)
.Add("Setup=")
.Add("OriginalSheetPath=" & OriginalDWG)
.Add("Has Plot Port=0")
.Add("Has3DDWF=0")
End If
End If
Next
.Add("[Target]")
.Add("Type=6")
.Add("DWF=" & PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf"))
.Add("OUT=" & IO.Path.GetDirectoryName(PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf")) & "\")
.Add("PWD=")
.Add("[MRU block template]")
.Add("MRU=0")
.Add("[MRU Local]")
.Add("MRU=3")
.Add("File0=" & IO.Path.GetDirectoryName(PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf")) & "\")
.Add("File1=" & IO.Path.GetDirectoryName(PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf")) & "\")
.Add("File2=" & IO.Path.GetDirectoryName(PathName.Replace("start.dsd", IO.Path.GetFileNameWithoutExtension(OriginalDWG) & ".pdf")) & "\")
.Add("[MRU Sheet List]")
.Add("MRU=0")
.Add("[AutoCAD Block Data]")
.Add("IncludeBlockInfo=0")
.Add("BlockTmplFilePath=")
.Add("[SheetSet Properties]")
.Add("IsSheetSet=FALSE")
.Add("IsHomogeneous=FALSE")
.Add("SheetSet Name=")
.Add("NoOfCopies=1")
.Add("PlotStampOn=FALSE")
.Add("ViewFile=FALSE")
.Add("JobID=0")
.Add("SelectionSetName=")
.Add("AcadProfile=<<Профиль без имени>>")
.Add("CategoryName=")
.Add("LogFilePath=")
.Add("IncludeLayer=FALSE")
.Add("LineMerge=FALSE")
.Add("CurrentPrecision=")
.Add("PromptForDwfName=TRUE")
.Add("PwdProtectPublishedDWF=FALSE")
.Add("PromptForPwd=FALSE")
.Add("RepublishingMarkups=FALSE")
.Add("PublishSheetSetMetadata=FALSE")
.Add("PublishSheetMetadata=TRUE")
.Add("3DDWFOptions=0 1")
End With
IO.
File.
WriteAllLines(PathName.
Replace(".dsd",
"_1251.dsd"), DsdFile, System.
Text.
Encoding.
GetEncoding(1251))
Make_DSD_File = True
Else
MsgBox("Файл " & PathName & " не может быть переведен в PDF поскольку отсутствуют листы, настроенные на принтер DWG_To_PDF_Gallurgy.pc3")
Exit Function
End If
Return Make_DSD_File
End Function
3. Запускаем AcCoreConsole.exe и Publish.scr:
Publish.scr
_filedia
0
_-publish
C:\Users\PASHIN~1\AppData\Local\Temp\DWG2PDF22032017172702888554\start_1251.dsd
_filedia
1
Как я запускаю AcCoreConsole.exe:
Dim ExecutablePath As String = "C:\Program Files\Autodesk\AutoCAD 2014\accoreconsole.exe"
Dim arg As String = " /i """ & Path & """ /s """ & TempFolder &
"\" & TempSCRFile & """ /l en-US"
DXF_OUT_START(ExecutablePath, arg)
Public Sub DXF_OUT_START(ByVal ExecutableAppPath As String, ByVal Args As String)
Try
Dim connect As System.Diagnostics.Process
connect = New System.Diagnostics.Process()
With connect
.StartInfo.FileName = ExecutableAppPath
.StartInfo.Arguments = Args
.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
.StartInfo.UseShellExecute = False
.StartInfo.RedirectStandardOutput = True
.StartInfo.CreateNoWindow = True
.Start()
Dim result2 As String = connect.StandardOutput.ReadToEnd ' Вот без преувеличения - это ВАЖНАЯ строка! Она не даёт подвисать AcCoreConsole.exe!!! Почему? Не знаю пока.
End With
Catch ex As Exception
End Try
End Sub
Дополнительно:
1. Если тестировать будете с помощью BAT-файла, то кодировка должна быть OEM-866 (или просто 866). Содержание файла:
"C:\Program Files\Autodesk\AutoCAD 2014\accoreconsole.exe" /i "D:\Пашин Евгений\Рабочий стол\Лоция checker\для Пашина\22.132-04501-АП\22.132-04501-АП-17-Кабельный журнал.dwg" /s "C:\Users\PASHIN~1\AppData\Local\Temp\DWG2PDF22032017172702888554\Publish.scr" /l en-US
Pause
2. SCR - файлы должны быть в кодировке UTF-8 (без BOM)
3. DSD - файлы должны быть в кодировке 1251
4. К сожалению, нет обратной связи с AcCoreConsole.exe (это я хотел бы как-то исправить, если кто знает как - подскажите!)
5. Пока неизвестно как всё это работает с файлами, созданными в разных вертикальных решениях AutoCAD-a.
6. Факт: вместо 10 минут (по старому варианту) вся обработка и публикация для 19 файлов заняла чуть менее 2 минут!!! Попробовал публикацию файлов с подложками, который старый вариант вообще никак не мог опубликовать, это решение выполнило публикацию за 6 секунд. Это просто неслыханно круто!
Вот видео готового решения:
Проверил для AcCoreConsole.exe AutoCAD 2017 - тоже отлично работает!