This may be a non-issue for a lot of folks anymore, but I was still having problems. The scenario:
I had written a VB.Net program that would check a file into our workgroup vault. The O/S is a 64 bit environment. SolidWorks is 2013, 64 bit version. As we all know, the vault was throwing the error due to the mismatch in environnents (pdmw is a 32 bit environment). What to do?
First off, the strategy. Essentially what I am doing is saving files in SolidWorks, setting them to read-only, then saving their file location to an Excel file. Once my list has been completed I automatically kick off an external executable that was programmed and compiled for a 32 bit environment. The external executable opens the excel file, works its way through the list, checking in each item. Once the executable completes and closes then the original program reloads each file. Simple, right? Yeah........
So, the code. Here's the code that builds the excel file. Note that it is very important that you fully close the excel file through code
Private Sub updateIDs()
Dim origFile As String
Dim tempMod As ModelDoc2
Dim tempDir As String = "C:\work"
Dim excelRowCounter As Integer = 2
Dim excelApp As New excel.Application
Dim ExcelWbk As excel.Workbook = excelApp.Workbooks.Add()
Dim ExcelSht As excel.Worksheet = ExcelWbk.Worksheets(1)
Dim loginInfo As List(Of String) = getLoginInfo()
Dim excelName As String = tempDir & "\loginList.xlsx"
Dim openedFileList As New List(Of String)
If Not My.Computer.FileSystem.DirectoryExists(tempDir) Then
My.Computer.FileSystem.CreateDirectory(tempDir)
End If
tempMod = swApp.ActiveDoc
origFile = Path.GetFileName(tempMod.GetPathName)
With ExcelSht
.Range("A1").Value = "Original File Name"
.Range("B1").Value = "Copied File Name"
.Range("C1").Value = "Description"
.Range("D1").Value = "User Name"
.Range("E1").Value = "Password"
.Range("F1").Value = "Successful"
.Range("G1").Value = "Status"
.Range("H1").Value = "Revision"
End With
For Each entry As DictionaryEntry In updateIDList
Dim temp As Object
temp = entry.Value
If openFile(temp(0)) Then
Dim swxModel As ModelDoc2
swxModel = swApp.ActiveDoc
openedFileList.Add(Path.GetFileName(swxModel.GetPathName))
Dim docName As String = Path.GetFileName(swxModel.GetPathName)
If changeOwnership(docName, True) Then
Dim propMan As CustomPropertyManager = swxModel.Extension.CustomPropertyManager("")
propMan.Add2("PartID", swCustomInfoType_e.swCustomInfoText, "")
propMan.Set("PartID", temp(1))
Dim desc As String
Dim newFileName As String
newFileName = tempDir & "\" & Path.GetFileName(swxModel.GetPathName)
desc = propMan.Get("Description")
If desc Is Nothing Then
desc = ""
End If
swxModel.SaveSilent()
swxModel.SetReadOnlyState(True)
'My.Computer.FileSystem.CopyFile(swxModel.GetPathName, newFileName)
With ExcelSht
.Range("A" & excelRowCounter).Value = swxModel.GetPathName
.Range("B" & excelRowCounter).Value = newFileName
.Range("C" & excelRowCounter).Value = desc
.Range("D" & excelRowCounter).Value = loginInfo(0)
.Range("E" & excelRowCounter).Value = loginInfo(1)
End With
excelRowCounter = excelRowCounter + 1
End If
If origFile <> docName AndAlso Not docAlreadyOpen Then
swApp.CloseDoc(docName)
swApp.ActivateDoc(origFile)
End If
End If
Next
ExcelSht.SaveAs(excelName)
ExcelWbk.Close()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
Marshal.ReleaseComObject(ExcelSht)
Marshal.ReleaseComObject(ExcelWbk)
Marshal.FinalReleaseComObject(ExcelSht)
Marshal.FinalReleaseComObject(ExcelWbk)
excelApp.Quit()
Marshal.FinalReleaseComObject(excelApp)
Dim processID As Integer
Dim proc As System.Diagnostics.Process
processID = Process.Start("C:\SolidWorks Data\TDS\Add-Ins\TDS AddIn Manager\Buttons\checkInExecutible.exe").Id
proc = Process.GetProcessById(processID)
Do While Not proc.HasExited
Thread.Sleep(1000)
'ProgressBar1.Value = ProgressBar1.Value + 10
Loop
reloadDocs(origFile)
swApp.ActivateDoc(origFile)
Me.BringToFront()
End Sub
____________________________________________________________________________________________________
And here's the code in the executible (Note: must be compiled to an x86 environment only!!)
Imports PDMWorks
Imports System.IO
Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices
Module Module1
Sub Main()
Dim connection As New PDMWConnection
Dim excelName As String = "C:\work\loginList.xlsx"
Dim excelApp As New Excel.Application
excelApp.Visible = False
Dim ExcelWbk As Excel.Workbook = excelApp.Workbooks.Open(excelName)
Dim ExcelSht As Excel.Worksheet = ExcelWbk.Worksheets(1)
Dim excelRng As Excel.Range
Dim lastRow As Integer = ExcelSht.UsedRange.Rows.Count
Dim userName As String = ExcelSht.Range("D2").Value.ToString
Dim password As String = ExcelSht.Range("E2").Value.ToString
Dim partCount As Integer
Dim assyCount As Integer
For j = 2 To lastRow
Dim ext As String = Path.GetExtension(ExcelSht.Range("A" & j).Value.ToString)
If ext = ".sldprt" Then
partCount = partCount + 1
Else
assyCount = assyCount + 1
End If
Next
For k = 0 To 1
Dim partInstCount As Integer = 0
Dim assyInstCount As Integer = 0
For i = 2 To lastRow
Dim docPath As String = ExcelSht.Range("A" & i).Value.ToString
Dim extension As String = Path.GetExtension(docPath)
Select Case k
Case 0
If extension = ".sldprt" Then
partInstCount = partInstCount + 1
Console.WriteLine("Checking in part file " & partInstCount.ToString & " of " & partCount.ToString)
Continue For
Else
GoTo continuethisloop
End If
Case 1
If extension = ".sldasm" Then
assyInstCount = assyInstCount + 1
Console.WriteLine("Checking in assembly file " & assyInstCount.ToString & " of " & assyCount.ToString)
Continue For
Else
GoTo continuethisloop
End If
End Select
'Console.WriteLine("Checking in file " & (i - 1).ToString & "of " & (lastRow - 1).ToString)
Dim doc As PDMWDocument = Nothing
Dim docName As String = Path.GetFileName(docPath)
Dim description As String = Convert.ToString(ExcelSht.Range("C" & i).Value)
Dim status As String = ""
Dim project As String = ""
Dim revision As String = ""
Dim number As String = ""
Dim references As Object = Nothing
'connection = CreateObject("pdmworks.Ipdmwconnection")
connection.Login(userName, password, "tds-ninjitsu")
If connection IsNot Nothing Then
doc = connection.GetSpecificDocument(docName)
If doc Is Nothing Then
connection.Logout()
connection.Login(userName, password, "tds-roku")
doc = connection.GetSpecificDocument(docName)
End If
End If
If doc IsNot Nothing AndAlso doc.Owner = userName Then
Dim newDoc As PDMWDocument
project = doc.project
status = doc.GetStatus
number = Path.GetFileNameWithoutExtension(docName)
newDoc = connection.CheckIn(docPath, project, number, description, "", PDMWRevisionOptionType.Default, revision, status, False, references)
If newDoc IsNot Nothing Then
ExcelSht.Range("F" & i).Value = "True"
Else
ExcelSht.Range("F" & i).Value = "False"
End If
Else
ExcelSht.Range("F" & i).Value = "False"
Exit Sub
End If
If connection IsNot Nothing Then
connection.Logout()
End If
continuethisloop: Next
Next
ExcelWbk.Save()
ExcelWbk.Close()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
Marshal.ReleaseComObject(ExcelSht)
Marshal.ReleaseComObject(ExcelWbk)
Marshal.FinalReleaseComObject(ExcelSht)
Marshal.FinalReleaseComObject(ExcelWbk)
excelApp.Quit()
Marshal.FinalReleaseComObject(excelApp)
End Sub
End Module
_________________________________________________________________________________________
And finally, the update code
Private Sub reloadDocs(ByVal origFile As String)
Dim excelName As String = "C:\work\loginList.xlsx"
Dim excelApp As New excel.Application
excelApp.Visible = False
Dim ExcelWbk As excel.Workbook = excelApp.Workbooks.Open(excelName)
Dim ExcelSht As excel.Worksheet = ExcelWbk.Worksheets(1)
Dim lastRow As Integer = ExcelSht.UsedRange.Rows.Count
For i = 2 To lastRow
If Path.GetExtension(ExcelSht.Range("A" & i).Value) = ".sldprt" AndAlso ExcelSht.Range("F" & i).Value = "True" Then
If openFile(, ExcelSht.Range("A" & i).Value) Then
Dim tempMod2 As ModelDoc2
tempMod2 = swApp.ActiveDoc
tempMod2.ReloadOrReplace(True, tempMod2.GetPathName, True)
If origFile <> Path.GetFileName(tempMod2.GetPathName) AndAlso Not docAlreadyOpen Then
swApp.CloseDoc(Path.GetFileName(tempMod2.GetPathName))
End If
End If
End If
Next
For i = 2 To lastRow
If Path.GetExtension(ExcelSht.Range("A" & i).Value) = ".sldasm" AndAlso ExcelSht.Range("F" & i).Value = "True" Then
If openFile(, ExcelSht.Range("A" & i).Value) Then
Dim tempMod2 As ModelDoc2
tempMod2 = swApp.ActiveDoc
tempMod2.ReloadOrReplace(True, tempMod2.GetPathName, True)
If origFile <> Path.GetFileName(tempMod2.GetPathName) AndAlso Not docAlreadyOpen Then
swApp.CloseDoc(Path.GetFileName(tempMod2.GetPathName))
End If
End If
End If
Next
ExcelWbk.Close()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
Marshal.ReleaseComObject(ExcelSht)
Marshal.ReleaseComObject(ExcelWbk)
Marshal.FinalReleaseComObject(ExcelSht)
Marshal.FinalReleaseComObject(ExcelWbk)
excelApp.Quit()
Marshal.FinalReleaseComObject(excelApp)
End Sub
So, there you go, it's that easy
Enjoy!
Jason
SolidworksApi macros