Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Accessing the clipboard... Should be easy?

I just got in touch with .NET though a simple problem I wanted to resolve with the Macros IDE in Visual Sutdio. Just this incursion showed me how big a world .NET can be.

I want do a very simple macro that takes the current path of my source file and posts it to the clipboard. The code looks a bit like this:

Sub CopyActivePath()
currentFilePath = DTE.ActiveDocument.Path + DTE.ActiveDocument.Name
Clipboard.SetDataObject(currentFilePath)
End Sub

But when I execute the macro, an exception is thrown saying that the current thread isn't set to Single Thread Apartment. This has to be set before OLE calls can be made. The thing is, I don't have access to the current thread that I assume, belonds to VisualStudio.

I have tried creating a thread, setting the correct apartment, and doing the clipboard stuff there, but to no avail.

How do I go about doing this simple task with VB macros in VS .NET? I have seen references to accessing COM objects from .NET clients but I don't know where I should find the COM object responsible for the clipboard.

David Genest
Thursday, September 19, 2002

Well, it looks to me like your problem is with “currentFilePath”. If take your code and set “currentFilePath = Application.StartupPath”, it works fine for me.

I don’t have any experience with DTE, but I think the problem is with “currentFilePath = DTE.ActiveDocument.Path + DTE.ActiveDocument.Name”. Could it be the +? Maybe it needs to be &?

Sorry I can’t give you more than that.

Marc LaFleur
Thursday, September 19, 2002

The error means what it says.  Are you doing this from an executable?  If so it's main should be marked STA.  If you are doing this from an activated component you can spin up a new thread in STA and perform the operation inside this thread.  I have used this effectively with remoted singletons.

Chris Kinsman
Thursday, September 19, 2002

As I mentionned, the code is a macro called from Visual Studio .NET, so the apartment is already set to MTA. I have tried putting the code in a thread like this:

Private Sub CopyToClipboard()
    Dim currentFilePath As String
    currentFilePath = DTE.ActiveDocument.Path + DTE.ActiveDocument.Name
    Clipboard.SetDataObject(currentFilePath)
End Sub

Sub CopyActivePath()
      Dim thread As New System.Threading.Thread(AddressOf CopyToClipboard)
      thread.ApartmentState = Threading.ApartmentState.STA

      thread.Start()
      thread.Join()
    End Sub

But on execution this code breaks with an unhandled exception of type System.Runtime.InteropServices.COMException. Additional information: Call was rejected by callee.

What is wrong? Is there something special to do because it is a VB macro executed from the Visual Studio IDE?

David Genest
Thursday, September 19, 2002

The "Call was rejected by callee." was being caused by VS.NET rejecting this call on another thread. (Not by the COM Clipboard call which caused the 1st errror message)

The Solution:
Get the ActiveDocument.Path etc on the current thread and stash in a global variable, then, as you did, create the 2nd thread with appropriate ApartmentState, just so that you can call Clipboad.SetDataObject()...
-------------------
Private m_currentFilePath As String

Sub CopyActivePath()
    m_currentFilePath = DTE.ActiveDocument.Path + DTE.ActiveDocument.Name

    Dim thread As New System.Threading.Thread(AddressOf CopyToClipboard)
    thread.ApartmentState = Threading.ApartmentState.STA

    thread.Start()
    thread.Join()
End Sub

Private Sub CopyToClipboard()
  'Note 2nd parameter too
    Clipboard.SetDataObject(m_currentFilePath, True)
End Sub

Maybe MS will get the "Macro thread" set up in STA mode in future (or at least give an easy way to configure it) so you don't have to jump through these hoops!

HTH!

Dunc
Thursday, September 19, 2002

Thank you very much! This works. I don't quite understand why it didn't work on my version, but that answer must lie in all the magic .NET does for us under the hood (which in my opinion is a mixed blessing)...

Thanks!

David Genest
Friday, September 20, 2002

*  Recent Topics

*  Fog Creek Home