Setting Clipboard data object with - copy after app exits - bool to true - c#

I have a line of code that sets text to the clipboard:
Clipboard.SetDataObject(clipBoardExceptions);
When I try to set this data object to also persist after the application exits I get an error that the clipboard can't open:
Clipboard.SetDataObject(clipBoardExceptions, true);
Produces:
the second arg: {"OpenClipboard Failed (0x800401D0 (CLIPBRD_E_CANT_OPEN))"}
This exception was originally thrown at this call stack:
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(int, System.IntPtr)
in Marshal.cs System.Windows.Clipboard.Flush()
System.Windows.Clipboard.CriticalSetDataObject(object, bool)
System.Windows.Clipboard.SetDataObject(object, bool)

Related

Can I pass an error message from a C# executable out into a VBScript

I have a C# command executable I created. In it, I have built some error handling. I would like to be able to pass these thrown errors out of the program into another script that the users will have control over (in VBS). I have seen I can set the Environment.Exit integer, but can I send my error message?
As #SLaks mentioned: write the error message to STDERR. If you run your executable via the Exec method you can get the exit code and error message like this:
Set ex = CreateObject("WScript.Shell").Exec("C:\path\to\your.exe")
While ex.Status = 0
WScript.Sleep 100
Wend
exitcode = ex.ExitCode
errormsg = ex.StdErr.ReadAll

Error When I Copy Range From Excel and Paste as Bitmap on Powerpoint

I am running the folowing C# code:
foreach(PictureObj pObj in this.picture_list) {
pObj._Picture.Copy();
slide.Shapes.PasteSpecial(Microsoft.Office.Interop.PowerPoint.PpPasteDataType.ppPasteBitmap);
foreach(Microsoft.Office.Interop.PowerPoint.Shape s in shapes) {
if(s._Name.Equals(pObj._Name)){
s.LockAspectRatio = Microsoft.Office.Core.MsoTriState.msoFalse;
s._Width = pObj._Width;
s._Height = pObj._Height;
s._Left = pObj._Left;
s._Top = pObj._Top;
}
}
}
pObj._Picture propert is of type Microsoft.Office.Interop.Excel.Range.
If I run the code on the debugger one step at a time it works but when I actualy try to run the program I get the folowing error on the PasteSpecial method:
Shapes (unknown member) : Invalid request. Clipboard is empty or contains data which may not be pasted here.
somethimes it does paste one or two pictures before it stops, I suspect the clipboard is out of sync. If my suspicions are correct, how do I wait for the clipboard to finish doing what it needs to do?
If this is not the problem then how do I get the desire result?

Why does my code throw an exception when I try to scan using WIA?

I'm making an application on C# Winforms which scans documents and places them into a PictureBox, However when I attempt to scan it throws an exception saying "Object Reference not set to an instance of an object" and will not allow me to continue, the stack trace is as below;
To clarify, this is a work project in case anyone gets alarmed by some of the class names.
AbDesktop.exe!AbDesktop.FrmCreditCards.ScanSetup() Line 39 C#
AbDesktop.exe!AbDesktop.FrmCreditCards.ScanFrontBtn_Click(object sender, System.EventArgs e) Line 94 + 0x8 bytes C#
[External Code]
AbDesktop.exe!AbDesktop.Program.Main(string[] args) Line 26 + 0x20 bytes C#
[External Code]
this is the code that is causing the issue;
public void ScanSetup()
{
WIA.CommonDialog dialog = new WIA.CommonDialog();
ImageFile scannedImage=null;
scannedImage = dialog.ShowAcquireImage(
WiaDeviceType.ScannerDeviceType,
WiaImageIntent.UnspecifiedIntent,
WiaImageBias.MaximizeQuality,
FormatID.wiaFormatPNG,
true, true, false);
scannedImage.SaveFile("C:/Users/reece.cottam/Pictures");
}
and this is the button that executes the above code when the click event is fired
private void ScanFrontBtn_Click(object sender, EventArgs e)
{
ScanSetup();
ImageFile IF = new ImageFile();
FrontScanBox.Image = IF.LoadFile("scannedimage.png");
}
Any help would be greatly appreciated.
EDIT
The line of code causing the error is ScannedImage.Savefile
Without extra information about which line throws the exception, I would guess that it's the line scannedImage.SaveFile(...); since the documentation for CommonDialog.ShowAcquireImage(...) states that a null value may be returned. In this case, when you try to operate on the variable scannedImage, you could be attempting to operate on a null reference.
The Documentation is pretty clear, the ShowAcquireImage method Returns an ImageFile object on success, otherwise returns Nothing..
scannedImage is null because this method was not successful, you need to look at the parameters you are passing in here, read the documentation and adjust them appropriately until you are getting the image you want back.
Have you tried specifying an actual file, instead of just the directory to save to?
scannedImage.SaveFile("C:/Users/reece.cottam/Pictures/test.png");
The lack of a decent filename might cause errors in the SaveFile function.
Though that should be visible in the Exception details.

Set value of cell in add in

I will explain everything that I have found but in short I just want to set the value of cell A1 in code behind. I have tried Create Excel Add-in - get cell value plus other links and all those techniques work only if I run them on a macro but I want execute them from a function.
So let me start explaining:
I do not understand why I get a wierd behaviour when I run the same code on a function versus a Sub. Take the following example:
Dim TimeToRun
Sub Macro1()
'Dim addIn As COMAddIn
'Dim automationObject As Object
'Set addIn = Application.COMAddIns("ProbeAddIn")
'Set automationObject = addIn.Object
'automationObject.ImportData
MsgBox "Hello world"
End Sub
Sub Macro2()
TimeToRun = Now + TimeValue("00:00:01")
Application.OnTime TimeToRun, "Macro1" ' run Macro1 on 1 seconds
End Sub
Function Test()
TimeToRun = Now + TimeValue("00:00:01")
Application.OnTime TimeToRun, "Macro1" ' run Macro1 on 1 seconds
End Function
Note that Macro2 and function Test have the same code. Why is it that if I run Macro2 it works ok (message box shows up). But if I go to a a cell and type =Test() then I get an error even though I have the same code !
The reason why am I showing this example is because the code that I have commented out on Macro1 works great if I run it by running the macro directly. If I place that code inside the function Test it does not work. That code is executing the following method in my add-in project on visual studio:
The exception is:
System.Runtime.InteropServices.COMException was unhandled by user code
HResult=-2146827284 Message=Exception from HRESULT: 0x800A03EC
Source="" ErrorCode=-2146827284 StackTrace:
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes,
MessageData& msgData)
at Microsoft.Office.Interop.Excel.Range.set_Value2(Object value)
at ReadWrite.ImportData() in C:\Users\Antonio\Dropbox_Temp\visual studio\Probe add in
test\ProbeAddIn\ProbeAddIn\Class1.cs:line 82 InnerException:
I got that exception because I ran:
Function Test()
Dim addIn As COMAddIn
Dim automationObject As Object
Set addIn = Application.COMAddIns("ProbeAddIn")
Set automationObject = addIn.Object
automationObject.ImportData
End Function
Instead of
Sub Test()
Dim addIn As COMAddIn
Dim automationObject As Object
Set addIn = Application.COMAddIns("ProbeAddIn")
Set automationObject = addIn.Object
automationObject.ImportData
End Function
How can I make the code inside a macro and function run the same way? I want to trigger the execution of that method when user types in a formula not when the user runs a macro. Even if I have the function run the macro I get the same exception The only way I do not get an exception is if the first thing that runs is a macro...
Not sure, but the issue you have may be due to the fact that when your function is fired the Excel application is in edit mode and so cannot accept any input from outside hence the exception when you try to insert data.
If you want to update a cell in a continuous way in a clean manner what you need is a RTD server.
From your cells you will simply call :
=RTD("my.super.rtdserver",,"mydata")
From time to time your RTD server will notify Excel of new data and lets Excel call-back to retrieve them when it is ready.

Screenshot of VBA editor in debug mode in terminal, or use Excel DOM to find error line and desc in VBA editor?

An Excel workbook is called by a command line, which itself is launched from c# (3.5). The workbook runs, but there is an error in the VBA. For example, a column is missing in a pivot and Excel prompts the user with an error message, with the option to "debug".
From the process in C#, we can detect that the error window is open, and we take a screenshot of the error message, and then we close the error box.
If this was an interactive session, Excel would then present the VBA editor, in debug mode, with the line where the error occurred highlighted.
However, because this is running in an unattended terminal session, we are then unable to take a screenshot of the VBA editor (the screenshot is a black screen).
We are then able to close the excel program, using the windows PID.
The questions is: how do we either get a screenshot of the VBA editor, or how do we bind (with COM or interop) with the Excel in debug mode, and traverse the dom to find the error line, and possibly error message?
(1) If you have authoring control of the Excel workbook(s), you can insert line numbers and a error handler to write to file Err.Number, Err.Description, Err.Source, Erl.
(2) If (1) is not an option, but you can set Macro Security on the host to allow programmatic control of the Visual Basic project, then you can get the active line number:
Dim xl As excel.Application
Dim StartLine As Long, StartColumn As Long, EndLine As Long, EndColumn As Long
Set xl = GetObject(, "Excel.Application")
xl.VBE.ActiveCodePane.GetSelection StartLine, StartColumn, EndLine, EndColumn
Debug.Print StartLine, StartColumn, EndLine, EndColumn
(3) If neither (1) nor (2) is an option, it is a bit hairy, but you can copy out the bitmap contents of the window: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183402%28v=vs.85%29.aspx
The simplest solution if you have access to modify the VBA code might be to use On Error GoTo and a line label. This will stop the Debug message from popping up and instead, when a runtime error occurs, execution will jump to the specified label at which point you can access the information available in the global Err object. VBA does not have the concept of a try/catch block so this is pretty much the nearest proximally.
Sub Main()
On Error GoTo Catch
' Code that may trigger errors here...
GoTo Finally
Catch:
' Log Err info, etc...
Debug.Print "Error " & Err.Number & " - " & Err.Description
Finally:
' This is always reached last (error or no error)
End Sub
Snapshot of data structures, VBA excel
It sounds a lot like the question above in which I suggested to write the state of your code to a separate txt file (in the example, using a FileSystemObject) where you can afterwards analyze where you got stuck:
booleans on conditions / instantiation of objects, number on succesful loops, values contained in variables, well - whatever you want...).
In combination with an error handler (as suggested before) you can see where the code stopped + code / description of the error.
A copy-paste for your sake:
dim sFile As string
Dim FSO As FileSystemObject
Dim FSOFile As TextStream
sFile = "U:/Log.txt"
Set FSO = New FileSystemObject
Set FSOFile = FSO.OpenTextFile(sFile, 2, True)
FSOFile.writeline (<Descriptions+Property/variable value>)
FSOFile.Close set FSO = nothing
I agree that it is a more work, but you'll know where to find the bug.
All depends on how hard and often you need this, in combination with how long the code is that you need to describe. Since I am not aware of your situation, I cannot judge on that.
In the end, it seems a lot of work, but actually it's quite easy since it's just describing the code that is already there.
Hope it helps.

Categories