PDMW Check-In - No Valid Client License work-around

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