Click here to Skip to main content
15,949,686 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello

my program should export certain Excel files from a folder as an image (in SVG format) into another folder. This can be done by the Methods CopyAndSaveTo and ExportRangeAsImage and they do their job.
On the MainWindow I have a button that performs these two functions when it is clicked. I want the User who clicks on this button be informed (Progressbar) how far is this process (Copy + export).
I have tried to realise it using a BackgroundWorker and it works only if I comment the following code (in the Method ExportRangeAsImage):

Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage());
image.Save(ImagePath + Path.GetFileNameWithoutExtension(file) + ".svg");


Otherwise I get the following error message (
translated from German):

In System.NullReferenceException an exception of type "System.Drawing.dll" has occurred, but was this not processed in the user code.

Additional information: Object reference not set to an object instance.

If a handler is available for this exception, the program may continue to run safely.



Here is the whole code:
C#
private void UpdateDataOfLine1(object sender, ExecutedRoutedEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.DoWork += worker_DoWork;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.RunWorkerAsync();
        }



        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Contains("$") || files[i].Contains("~") || files[i].Contains("Thumb"))
                {
                    continue;
                }

                File.Copy(files[i], DestPath + Path.GetFileName(files[i]), true);

                string newFile = DestPath + Path.GetFileName(files[i]);

                ExPortRangeAsImage(newFile);

                (sender as BackgroundWorker).ReportProgress(i);
                Thread.Sleep(100);
            }
        }



        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Status.Value = e.ProgressPercentage;
        }


        public void ExPortRangeAsImage(string file)
        {
            var ExcelApp = new Microsoft.Office.Interop.Excel.Application();

            try
            {
                if (file.Contains("BeispielDatei"))
                {
                    Workbook wb = ExcelApp.Workbooks.Open(file);
                    Worksheet ws = (Worksheet)wb.Sheets[1];
                    Range range = ws.Range["A1:U35"];
                    range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
                    wb.Close(SaveChanges: false);
                    Marshal.ReleaseComObject(wb);
                }

                else
                {
                    Workbook wb = ExcelApp.Workbooks.Open(file);
                    Worksheet ws = (Worksheet)wb.Sheets[1];
                    Range range = ws.Range["A1:U35"];
                    range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
                    wb.Close(SaveChanges: false);
                    Marshal.ReleaseComObject(wb);
                }
            }

            finally
            {
                Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage());
                image.Save(ImagePath + Path.GetFileNameWithoutExtension(file) + ".svg");

                Marshal.ReleaseComObject(ExcelApp);
            }
        }


What I have tried:

C#
private void UpdateDataOfLine1(object sender, ExecutedRoutedEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.DoWork += worker_DoWork;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.RunWorkerAsync();
        }



        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Contains("$") || files[i].Contains("~") || files[i].Contains("Thumb"))
                {
                    continue;
                }

                File.Copy(files[i], DestPath + Path.GetFileName(files[i]), true);

                string newFile = DestPath + Path.GetFileName(files[i]);

                ExPortRangeAsImage(newFile);

                (sender as BackgroundWorker).ReportProgress(i);
                Thread.Sleep(100);
            }
        }



        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Status.Value = e.ProgressPercentage;
        }


        public void ExPortRangeAsImage(string file)
        {
            var ExcelApp = new Microsoft.Office.Interop.Excel.Application();

            try
            {
                if (file.Contains("BeispielDatei"))
                {
                    Workbook wb = ExcelApp.Workbooks.Open(file);
                    Worksheet ws = (Worksheet)wb.Sheets[1];
                    Range range = ws.Range["A1:U35"];
                    range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
                    wb.Close(SaveChanges: false);
                    Marshal.ReleaseComObject(wb);
                }

                else
                {
                    Workbook wb = ExcelApp.Workbooks.Open(file);
                    Worksheet ws = (Worksheet)wb.Sheets[1];
                    Range range = ws.Range["A1:U35"];
                    range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
                    wb.Close(SaveChanges: false);
                    Marshal.ReleaseComObject(wb);
                }
            }

            finally
            {
                Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage());
                image.Save(ImagePath + Path.GetFileNameWithoutExtension(file) + ".svg");

                Marshal.ReleaseComObject(ExcelApp);
            }
        }



Can you show me what I'm doing wrong or how I can realize it?
Are there other ways than BackgroundWorker?

Thank you in advance for your help!
Posted
Updated 3-Oct-16 4:49am
Comments
[no name] 2-Oct-16 20:12pm    
A null reference is the same for everyone. You are trying to use the methods or properties of an object that is null. We don't have your data or files so we can't debug it for you. You need to debug your code, find the null object and fix it.
Member 12741482 2-Oct-16 20:20pm    
the null object is returned by Clipboard.GetImage() and I dont unterstand why. Because both Methods work well if dont use the BackgroundWorker.

1 solution

Your issue is that you cannot access the clip board from a multi threaded application. Using the Thread class you can set whether it is STA or MTA...however i don't think it is possible to do that using the backgroundworker class (c# - How can I make a background worker thread set to Single Thread Apartment? - Stack Overflow[^]).

To set STA using Thread class you can do something like:

C#
Thread t = new Thread(AccessClipBoardHere());
t.SetApartmentState(ApartmentState.STA);
t.Start();
 
Share this answer
 
Comments
Member 12741482 3-Oct-16 11:24am    
Thank You for this solution but I don't unterstand how and where I should use it in my Code :(
David_Wimbley 3-Oct-16 11:28am    
Replace your background worker code with the code above

BackgroundWorker worker = new BackgroundWorker();            
worker.WorkerReportsProgress = true;            
worker.DoWork += worker_DoWork;            
worker.ProgressChanged += worker_ProgressChanged;   
worker.RunWorkerAsync();
And you could still use worker_DoWork, but just make it not have any parameters and fix any compiler errors due to this.
Member 12741482 3-Oct-16 11:42am    
Thanks! I try it right now...
Member 12741482 3-Oct-16 14:50pm    
if i remove the Background worker code if could not use worker_ProgressChanged, and worker_Completeted...
David_Wimbley 3-Oct-16 14:51pm    

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900