title: Cannot mark Excel workbook as Final
body: <p>The situation is as follows: </p>
  
  <p>We want to publish to a remote machine a locally edited file. This file could be of type Word, Excel, Powerpoint. Apparently, after the publishing to the remote machine, we would like the local document to be marked as final, in order to prevent the user from editing it again (, because the intented workflow is first downloading it from the remote server, editing the downloaded document and the publishing it back to the server).</p>
  
  <p>So, there is a bunch of code like this:</p>
  
  <pre><code>Public Sub setDocFinal()
  Select Case addin.HostType
      Case ADXOfficeHostApp.ohaWord
          Dim doc As Word.Document = Nothing
          Try
              doc = addin.WordApp.ActiveDocument
              doc.Final = True
          Catch ex As Exception
              Throw New Exception(Me.addin.getLabel("cannotSaveCopy", "Cannot Save the document."))
          Finally
              Marshal.ReleaseComObject(doc)
          End Try
      Case ADXOfficeHostApp.ohaExcel
          Dim doc As Excel.Workbook = Nothing
          Try
              doc = addin.ExcelApp.ActiveWorkbook
  
              doc.Final = True
              'doc.RefreshAll()
              'doc.CalculateUntilAsyncQueriesDone()
              'doc.Calculate()
  
          Catch ex As Exception
              Throw New Exception(Me.addin.getLabel("cannotSaveCopy", "Cannot Save the document."))
          Finally
              Marshal.ReleaseComObject(doc)
          End Try
      ' Powerpoint case intentionally skipped as is has same format/code
  End Select
  End Sub
  </code></pre>
  
  <p>The above code works pretty well for the Word case, but when it comes to Excel, it stacks on the popup which informs the user for the publish action to the remote server: 
  <a href="https://i.stack.imgur.com/pKMHC.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pKMHC.png" alt="enter image description here"></a></p>
  
  <p><strong>EDIT</strong><br/>
  At that particular point, the execution freezes (or maybe gets into an infinite internal loop, because the only available buttons in debugging mode are pause and stop) at the line of setting the document as final and it never reaches the <code>finally</code> statement (where we release the object). It also seems like the execution tries to return control back to the excel document, but nothing more than this notification occurs :</p>
  
  <p><a href="https://i.stack.imgur.com/EKbfL.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/EKbfL.png" alt="enter image description here"></a><br>
  <br/>Any idea of what is wrong in the above code, regarding the handling of Excel?
  <br/><em>The lines in comments display some trials I have been going through, while trying to find a solution around the net.</em></p>
  
  <p>In addition, here is also the popup's related code:</p>
  
  <pre><code>Private Sub doWork(ByVal action As String, ByVal e As System.ComponentModel.DoWorkEventArgs)
      Dim myDoc As MyDocument
      myDoc = DirectCast(e.Argument, MyDocument)
      System.Diagnostics.Debug.WriteLine("Post in Thread")
  
      Dim resultObject(3) As Object
      resultObject(0) = True
      resultObject(1) = myDoc
  
      Dim saveDocumentResult As SaveDocumentResult = Nothing
      Try
          Select Case action
              Case Constants.SAVE_DRAFT
                  saveDocumentResult = myDoc.getRequestService().saveDraft(myDoc.getSaveFile(), myDoc.getDocName(), myDoc)
              Case Constants.PUBLISH
                  saveDocumentResult = myDoc.getRequestService().publishDocument(myDoc.getSaveFile(), myDoc.getDocName(), myDoc)
                  myDoc.setDocFinal() 'this line makes the call to the above code
          End Select
  
          myDoc.updateDocumentProperty(Constants.VERSION, saveDocumentResult.version)
          myDoc.updateDocumentProperty(Constants.HASH, saveDocumentResult.hash)
  
          myDoc.setSaved(True)
          System.Threading.Thread.Sleep(1500)
      Catch ex As Exception
          resultObject(0) = False
          resultObject(2) = ex.Message
      Finally
          e.Result = resultObject
      End Try
  
  End Sub
  </code></pre>