none
How to limit Word document-level customisation to a single instance. RRS feed

  • Question

  • I am developing a document-level customisation for Word 2010 in VSTO 2012.  As I am making heavy use of events, I want to restrict the user to only having just a single document based on the customisation open at any time so that I can avoid the 'wrong' document reacting to any given event should the user switch between documents.

    I have tried accessing BuiltInDocumentProperties in order to read the 'Template' property but the method suggested by Microsoft here does not work.  It fails with an exception whenever I try to DirectCast or CType from ComObject to DocumentProperties.

    I have considered using a Mutex but this posting suggests that "the use of Mutexes is not appropriate to ensure singleton behaviour [because] mutuexes have thread affinity but VSTO customisations do not." Certainly I could not get it the suggested code to work for me.

    I am developing in VB.net so ideally any solution would be in that language.

    What alternative strategies can I use? This must be a fairly common requirement so how have others achieved it?

    Thank you in anticipation for anyone who is able to help me with this one.

    Paul

    Friday, June 13, 2014 4:09 PM

Answers

  • Hi Paul

    The only way to ensure that Word will start a new instance would be to change the settings in the Registry that are used when the application starts (DDE). There are command line switches that will force a new instance. However, unless you're working in a corporate environment and IT agrees to make this change to the installation default, it's not really practical...

    As far as I'm aware, Word has no built-in DocumentProperty named Template. A Word document does have a property AttachedTemplate. Is that what you want to use? DocObject.AttachedTemplate should return the full name of the template on which the document is based (or to which it was attached at a later time).

    And, in a general way, I recommend the DocumentChange event to track when the user switches between documents.


    Cindy Meister, VSTO/Word MVP, my blog

    Friday, June 13, 2014 6:13 PM
    Moderator
  • Cindy,

    Your nudge to look at DocObject.AttachedTemplate took me in the right direction, thank you.

    I have achieved singular use of my template in the following way. All code is in the ThisDocument class:

    Private Sub ThisDocument_New() Handles Me.New

    If OpenDiariesCount() > 1 Then

    Me.Saved = True

    Me.Close()

    End If

    End Sub

    ** Similar code is required in ThisDocument_Open

    Private Function OpenDiariesCount() As Integer

    Dim count as Integer = 0

    Dim doc as Document

    On Error Resume Next

    For Each doc in ThisApplication.Documents

    If doc.AttachedTemplate.Name = "MyTemplateName" Then count = count + 1

    Next

    Return count

    End Function 

    _______________________

    Paul

    Tuesday, June 17, 2014 8:45 PM

All replies

  • Hi Paul

    The only way to ensure that Word will start a new instance would be to change the settings in the Registry that are used when the application starts (DDE). There are command line switches that will force a new instance. However, unless you're working in a corporate environment and IT agrees to make this change to the installation default, it's not really practical...

    As far as I'm aware, Word has no built-in DocumentProperty named Template. A Word document does have a property AttachedTemplate. Is that what you want to use? DocObject.AttachedTemplate should return the full name of the template on which the document is based (or to which it was attached at a later time).

    And, in a general way, I recommend the DocumentChange event to track when the user switches between documents.


    Cindy Meister, VSTO/Word MVP, my blog

    Friday, June 13, 2014 6:13 PM
    Moderator
  • Cindy,

    Your nudge to look at DocObject.AttachedTemplate took me in the right direction, thank you.

    I have achieved singular use of my template in the following way. All code is in the ThisDocument class:

    Private Sub ThisDocument_New() Handles Me.New

    If OpenDiariesCount() > 1 Then

    Me.Saved = True

    Me.Close()

    End If

    End Sub

    ** Similar code is required in ThisDocument_Open

    Private Function OpenDiariesCount() As Integer

    Dim count as Integer = 0

    Dim doc as Document

    On Error Resume Next

    For Each doc in ThisApplication.Documents

    If doc.AttachedTemplate.Name = "MyTemplateName" Then count = count + 1

    Next

    Return count

    End Function 

    _______________________

    Paul

    Tuesday, June 17, 2014 8:45 PM