
Background:
The first question you may ask is "Why would you ever want to use the server's clipboard to do anything?" Good question :). I came accross this problem when I was trying to write a pdf parser that would rasterize the front page and save it into a Bitmap object. From here, you can save it to a file, database, etc. To do this, I was using the Adobe Acrobat com library that comes with Adobe Acrobat 7.0. Unfortunatly, they do not have a function that allows you to simply save to a file. They do, however, let you copy the image to the clipboard and then recover it in whatever format you want.
Problem:
I found some great code here: http://www.codeproject.com/dotnet/pdfthumbnail.asp. This code was written for a C#/VB.Net Windows App and works great if used that way. However, when I tried to use this text in the OnClick event of an ASP Button control, i found that nothing was happening. Turns out, the CopyToClipboard command was working fine, b/c if I traced through, I could press ctrl+v and see the image perfectly. However, when the Clipboard.GetObject method was called, it was always returning Null.
Solution:
After much digging and 2 days of work, I stumbled on the reason: The thread started for the ASP.Net application did not have the right ApartmentState to read the Clipboard class. So, here is what I did to work around this:
protected void Button_Click(object sender, EventArgs e)
{
Thread cbThread = new Thread(new ThreadStart(CopyToClipboard));
cbThread.ApartmentState = ApartmentState.STA;
cbThread.Start();
cbThread.Join();
}
[STAThread]
protected void CopyToClipboard()
{
/*
In here, put the code that copies AND retrieves from the clipboard.
If you use global variables, the Bitmap you populate here can be used elsewhere in your code.
*/
}
Final Notes:
I do not recommend doing this in a multi-user environment as there is no guarentee that the user that copied to the clipboard will be the one who retrieves from it. Also, images/pdfs can be very large and the clipboard is slow.
I hope this is of some use to someone. It solved my problem and saved me $900 by not having to buy a PDF Rasterizer control. Feel free to respond and let me know if it helped you out or if you have any questions.
~ Oleg Fridman
18 Answers, 1 is accepted
This is an awesome hack. Thanks for posting it -- it can be a real lifesaver for people that are locked into using a component that deals with the clipboard.
People that want to delve a bit deeper into COM apartments and managed and unmanaged threading might wish to check this article out.
Greetings,
Hristo Deshev
the telerik team

Could you please email me some sample code which works for this.
I am having problems creating the Acro.Exch object inside a web page when I run it under some circumstances.
Thanks in Advance.
Eric Dell'Oro
delloro@optusnet.com.au

I agree with Hirsto. This is a gem and I hope that you have taken the time to post it on another "code sharing" site (like Code Project) so it doesn't get lost.
One question: What is the scope of data saved to the server's clipboard? Is it scoped per user session or is info on the clipboard available to the entire application?
Thanks~

Eric,
I have posted an example on my server b/c I want everyone to be able to see it.
You can access it here: http://www.owebtech.com/example.zip
Some quick notes:
This is part of a much bigger project and contains some unrelated code. I did my best to clean it up a little but I am positive I missed some stuff.
Important code:
I would check out the Submit_Form function to see how the thread is created and set to ApartmentState.STA appropriatly.
Check out the CreatePDFImage function to see the actual function run by the thread.
I really hope this helps you guys out.
-Oleg

I don't know the exact answer to your question but every test that I have run so far suggests that it has an application-wide scope which is why I made the note that it should not be made in a multi-user environment. This uses the actual clipboard of the server so it will overwrite whatever is on it with the new data every time a request like this is made.
Hope that answers that question,
Oleg

[System.Runtime.InteropServices.ExternalException] = {"Requested Clipboard operation did not succeed."}
for the code of line ..
clipboardData = Clipboard.GetDataObject();
please help me.

Thanks for your interest in this code.
Try this for me:
Put a break in the code right before the "Clipboard.GetDataObject();" line but after the pdfPage.CopyToClipboard(pdfRect, 0, 0, 100); line.
Now, when the break hits, open up Paint on the server (or even Clipboard viewer), and see if there is anything there. If there is, what type is it? If you did it with paint, you should be able to hit Edit->Paste and see the pdf file in paint.
Also, are you sure you are running the line "Clipboard.Clear();"?
I have heard of problems with multiple items in the clipboard if it is not cleared every time.
I was not able to find much online about this error...
Sorry Sam. Give those two things a shot and let me know.
-Oleg Fridman

Hi,
We are actually using the adobe acrobat 6.0 sdk for generating the thumbnails of the pdf pages. using the code from the following link.
And this code is working fine on the win200o professional and Xp professional OS which is running with IIS5.0.
When we run this code on win2003 server machine which is running with IIS6.0 by default this code is not running properly. The main problem is we find out is with the introduction of new application pool concept in IIS6.0.
If we change the worker process isolation mode in IIS6.0 to be compatible with IIS 5.0 then the code runs fine but the report server(SQL server reporting services 2005) installed on the machine stops working.
We are not able to find the solution for this.
Note: To change the isolation mode in IIS 6.0. Here the link to find the step for this one

Oleg,
hi! code is working in win xp and .net framework 2005, but i have problems with .net 2003, this don't work.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim cbThread As Threading.Thread
cbThread = New Threading.Thread(New Threading.ThreadStart(AddressOf CopyToClipboard))
cbThread.ApartmentState = Threading.ApartmentState.STA
cbThread.Start()
cbThread.Join()
End Sub
<STAThread()> _
Protected Sub CopyToClipboard()
Dim objClipboard As IDataObject
objClipboard = Clipboard.GetDataObject
If Not objClipboard Is Nothing Then
If (objClipboard.GetDataPresent(DataFormats.Bitmap)) Then
' never enter here
Dim pBitmap As Bitmap
pBitmap = objClipboard.GetData(DataFormats.Bitmap)
pBitmap.Save("C:\Inetpub\wwwroot\images\imgtemp.bmp")
Me.Image1.ImageUrl = "http:\\localhost\images\imgtemp.bmp"
End If
End If
End Sub
if you help mee i apprecired.
Cu

I hope you can find something online about it. Again, sorry I cannot help.

Good Logic
Thanks

Thanks

thanks for the wornderful peice of code...worked for me as i had to deal with PDF which where very small (1 Page) in size and saved quite a bit of effort and money...:)

i am working with vs2008 (web application) and I want to copy some content from an excel sheet and and using the clipboard i want to copy the contents in a gridview
I have tried using Clipboard.GetDataObject() but no matter what ever i do it is always returning null so can anyone suggest me solution of how to implement this.
please check the below url for teh way i want :
http://www.nitobi.com/products/grid/copypaste/
regards,
vamsi.

Is there any better approach than what I tried.
Any suggestion to me please.
Sandeep
You can use HttpContext.Current.Response.AddHeader and HttpContext.Current.Response.ContentType methods inside a custom HttpHandler.
To open the file as an attachment you can use
response.AddHeader("content-disposition", "attachment; filename=" + contentSettings.FileName);
To open the file inline you can use
response.AddHeader("content-disposition", "inline; filename=" + contentSettings.FileName);
You could also open the document inside another custom control as shown in this demo or iframe.
Best wishes,
Ivan Dimitrov
the telerik team

still getting the error that "Clipborad" is undefined.
how to over this?

Nice Trick..!!
Working great in Asp.net Web forms..:)
But same code is not working in MVC 4.
I have tried using Clipboard.GetDataObject() with Thread execution as per given trick, but got below error..
+++++++++
System.NullReferenceException: Object reference not set to an instance of an object. at thumb_MVC.Controllers.HomeController.CopyToClipboard() in
++++++++++
Is there any better approach than what I tried.
Any suggestion to me please.
Thanks in Advance.
Hello,
there are many ways to copy to clipboard:
Make sure to add the namespaces.
First Example:
using System; using System.Windows; public class Program { public static void Main() { Clipboard.SetText("Hello, clipboard"); Console.WriteLine(input); } }
Example 2
using System; using System.Threading.ThreadStateException; public class Program { public static void Main() { Thread thread = new Thread(() => Clipboard.SetText("String to be copied to clipboard")); thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA thread.Start(); thread.Join(); } }
Copy to Clipboard in C#