This command is unavailable because the license to use this application has expired - Excel Automation

722 Views Asked by At

I have a .NET Windows application (which is written in VB.Net, but the same occurs with C#) where I am getting a This command is unavailable because the license to use this application has expired error.

The stack trace to this error is: at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData) at Microsoft.Office.Interop.Excel.Range.Select()

The line of code that is failing is: wrksht.Range("A2").Select(). It does not always fail! It can work several times before failing or can fail the first time it is called.

To be clear about how the process works:

  1. A Word document is opened
  2. A chart is found (via a shape)
  3. The chart data is activated
  4. The worksheet is accessed
Dim chrt As _word.Chart = shp.Chart
chrt.ChartData.Activate()
Dim wrksht As _excel.Worksheet = chrt.ChartData.Workbook.WorkSheets(1)
wrksht.Range("A2").Select() 'Line that errors

The Windows application is running on a Terminal Services instance and Office 365 is using a Shared Activation License (which is activated). The same application runs successfully on a standalone PC using Office 365, but with a standard license.

Any ideas?

Additional Info

I have created a simple macro in Word to bypass any .Net/application issues. The macro errors every time on the .Select. However, if I change the .Select to .FormulaR1C1 = "TEST", then it completes. In fact all sorts of Word and Excel automation is working, it seems to only have issue with the .Select once the worksheet for the Word chart object is used.

See code:

Sub Test()
Dim shp As InlineShape
Dim chrt As Chart
Dim wrksht As Excel.Worksheet

    Set shp = getInlineShapeFromTitle("Score_Graph_Question_15964_4")
    Set chrt = shp.Chart
    
    chrt.ChartData.Activate
    Set wrksht = chrt.ChartData.Workbook.Worksheets(1)
    
    'wrksht.Range("A1").FormulaR1C1 = "TEST 1"
    wrksht.Range("A1").Select
    
    chrt.ChartData.Workbook.Application.Quit
End Sub

Private Function getInlineShapeFromTitle(title As String) As InlineShape
Dim shp As InlineShape
Dim shp1 As InlineShape
    
    For Each shp1 In ActiveDocument.InlineShapes
        If shp1.title = title Then
            Set shp = shp1
            Exit For
        End If
    Next
    
    Set getInlineShapeFromTitle = shp
End Function

Further Findings

The Office license is valid and activated, however, when Word opens Excel (via the chrt.ChartData.Activate command), Excel has "Unlicensed Product" in the title bar. If Excel is opened manually, it shows as licensed and activated. This image shows what is shown when Word opens Excel:

Image of Excel when opened by Word

If I choose to set the datasource of the chart from Word manually (not using VBA), Excel opens and the unlicensed product message is not in the title bar.

2

There are 2 best solutions below

0
user246821 On

This isn't an answer, but may be useful. It shows how you may do something similar without using late binding which allows one to enable Option Strict.

Add COM references (Project => Add Reference... => COM)

  • Microsoft Excel xx.x Object Library
  • Microsoft Word xx.x Object Library

Add the following Imports statement:

  • Imports Microsoft.Office.Interop
Private Sub Test(filename As String)
    Dim excelWorkbook As Excel.Workbook = Nothing
    Dim excelWorksheet As Excel.Worksheet = Nothing
    Dim wordApp As Word.Application = Nothing
    Dim wordDoc As Word.Document = Nothing

    If Not System.IO.File.Exists(filename) Then
        Throw New Exception($"Error - '{filename}' doesn't exist.")
    End If

    Try
        Debug.WriteLine($"filename: '{filename}'")

        'create new instance
        wordApp = New Word.Application()

        'open Word document
        wordDoc = wordApp.Documents.Open(DirectCast(filename, Object))

        Dim chrt As Word.Chart = Nothing

        If wordDoc.InlineShapes.Count > 0 Then
            For Each oShape As Word.InlineShape In wordDoc.InlineShapes
                chrt = oShape.Chart

                Debug.WriteLine($"Title: '{chrt.ChartTitle.Text}' ChartType: {chrt.ChartType.ToString()}")

                If chrt IsNot Nothing Then
                    chrt.ChartData.Activate()
                    excelWorkbook = DirectCast(chrt.ChartData.Workbook, Excel.Workbook)
                    excelWorksheet = DirectCast(excelWorkbook.Worksheets(1), Excel.Worksheet)

                    Debug.WriteLine($"Value: '{excelWorksheet.Range("A2").Cells().Value}'")

                    excelWorksheet.Range("B2").Select()
                    'excelWorksheet.Range("A2").FormulaR1C1 = "Test 1"
                End If
            Next
        End If
    Catch ex As Exception
        Debug.WriteLine($"Error - {ex.Message}")
        Throw
    Finally
        If excelWorksheet IsNot Nothing Then
            'release all resources
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelWorksheet)

            excelWorksheet = Nothing
        End If

        If excelWorkbook IsNot Nothing Then
            excelWorkbook.Close(DirectCast(False, Object))

            'release all resources
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelWorkbook)

            excelWorkbook = Nothing
        End If

        If wordDoc IsNot Nothing Then
            wordDoc.Close(DirectCast(False, Object))

            'release all resources
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(wordDoc)

            wordDoc = Nothing
        End If

        If wordApp IsNot Nothing Then
            wordApp.Quit()

            'release all resources
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(wordApp)

            wordApp = Nothing
        End If
    End Try
End Sub

Usage (assumes there is a Button with the name 'ButtonRun')

Private Sub ButtonRun_Click(sender As Object, e As EventArgs) Handles ButtonRun.Click
    Using ofd As OpenFileDialog = New OpenFileDialog()
        ofd.Filter = "Word Document (*.docx)|*.docx"

        If ofd.ShowDialog() = DialogResult.OK Then
            Test(ofd.FileName)
        End If
    End Using
End Sub

Resources:

0
TechyGypo On

This is very much a workaround and not necessarily a fix, but I am able to not get the error by turning off the "optional connected experiences" in Word's privacy settings:

Word privacy settings to turn off optional connected experiences

I don't know why this would be the case and it was found purely by luck. There must be some conflict between the Terminal Services instance and Office 365 using a Shared Activation License.

I found this article from MS for additional reading: https://learn.microsoft.com/en-us/deployoffice/privacy/optional-connected-experiences