How to properly handle COMException when writing to Excel cell? - c#

I have an application which writes values to one of 4 cells in an Excel worksheet. The sheet is roughly 30x30 cells. Normally this works fine but if the user happens to click on the worksheet while my app is running then a COMException is thrown. Note that the cell that is clicked on does not have to be one of those that is being written to by the app. I tried doing 3 retries (see code below) but this did not help.
What might be causing this error and what can I do to handle it better?
public bool WriteString(string id, string value)
{
for (int i = 0; i < RETRY; i++)
{
try
{
log.Debug(string.Format("XL write '{0}' to '{1}'", value, id));
Range range = GetCell(id);
range.Value2 = value;
return true;
}
catch (System.Runtime.InteropServices.COMException x)
{
log.Error(x);
Thread.Sleep(1);
}
}
return false;
}
System.Runtime.InteropServices.COMException (0x800AC472): Exception from HRESULT: 0x800AC472
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 Pruef.Net.TgtManager.StdTarget.Excel.ExcelTarget.WriteString(String id, String value)
at Pruef.Net.TgtManager.StdTarget.Excel.ExcelTarget.WriteDouble(String id, Double value)
at Pruef.Net.Model.IOManaged.DoOutput(OutputAction action)
at Pruef.Net.ViewModel.ExecuteViewModel.PerformAction(BaseAction action, Boolean ignoreStop)
at Pruef.Net.ViewModel.ExecuteViewModel.PerformAction(BaseAction action, Boolean ignoreStop)
at Pruef.Net.ViewModel.ExecuteViewModel.PerformActions(ObservableCollection`1 actions, Boolean ignoreStop)
at Pruef.Net.ViewModel.ExecuteViewModel.Execute(UnitOfTest uot)
Just found this question Exception from HRESULT: 0x800A03EC Error. Perhaps 'sleep'ing a bit longer might help...

Related

C# exception System.ArgumentException in dynamic object

I have the following code interacting with automation server via dynamic object:
class Program
{
static string strProgId = "MyAutomation.Document";
static dynamic pserver = null;
static void Main(string[] args)
{
try
{
Type tPserver = Type.GetTypeFromProgID(strProgId);
if (tPserver != null)
{
pserver = Activator.CreateInstance(tPserver);
}
pserver.About(null, 0);
pserver.OpenDataFile(IntPtr.Zero, true, "Test.dat");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
if (pserver != null)
{
pserver.FileExit();
}
}
}
As you can see, it creates an instance of automation server and is calling two methods on it. The first call works as expected. The second call throws the following exception:
e {"Could not convert argument 0 for call to OpenDataFile."} System.Exception {System.ArgumentException}
Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary> {System.Collections.ListDictionaryInternal}
HResult 0x80070057 int
I am not sure what is wrong here, since both methods have the same argument 0 and the first call works as expected. These methods are defined in ODL file as follows:
[id(20)] boolean About(long hWnd, long msgID);
[id(35)] boolean OpenDataFile(long hWnd, boolean bEmbed, BSTR* bsPfyFilePath );
Thank you for your help.

Exception while installing VFPOLEDB programmatically

I am trying to install VFPOLEDB driver via a console application.
I tried doing something like this
public void InstallVfpOledb()
{
Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
try
{
Installer installer = (Installer)Activator.CreateInstance(type);
installer.InstallProduct(#"C:\VFPOLEDBSetup.msi");
}
catch (Exception e)
{
Console.Write(e.ToString());
}
}
So when I run the program I get the following exception:
System.Runtime.InteropServices.COMException (0x80004005):
InstallProduct,PackagePath,PropertyValues at
System.RuntimeType.ForwardCallToInvokeMember(String memberName,
BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData&
msgData) at WindowsInstaller.Installer.InstallProduct(String
PackagePath, String PropertyValues) at
installtest.Program.Main(String[] args) line 22
I believe InstallProduct method has path and property values as parameters.
I am missing those values I guess.
Can anyone point me in the correct direction for the same?
This one works for me:
// using Microsoft.Deployment.WindowsInstaller in
// Microsoft.Deployment.WindowsInstaller.dll
try
{
Installer.InstallProduct(#"C:\VFPOLEDBSetup.msi","");
}
catch (Exception e)
{
Console.Write(e.Message);
}
It asks for permission if not run as administrator.

jqGrid weird exception upon calling databind

I have been using the latest MVC dll from Trirand and I am using the JqGrid.Databind() function to get data from the controller. Here is the code that I have written:
var listToBind = gridDataTable.Cast<IDictionary>().ToDataSource();
gridModel.ResourcePlanningGrid.DataSource = null;
JsonResult returnObject;
try
{
returnObject = gridModel.ResourcePlanningGrid.DataBind(listToBind.AsQueryable());
}
catch(Exception ex)
{
//Unknown Exception: delete the current session that holds the grid and
//restart the whole page
this.Session["ResourcePlanningGrid"] = null;
return FilterData();
}
Intermittently it throws an exception on the .DataBind() call that says that it parses a string that is not a valid Boolean. Has anyone encountered this before? Is there an existing fix for this? or should I find another way to pass values from a list to bind?
Here is the the exception stack trace.
at System.Boolean.Parse(String value)
at System.Convert.ToBoolean(String value)
at Trirand.Web.Mvc.JQGrid.get_AjaxCallBackMode()
at Trirand.Web.Mvc.JQGrid.DataBind()
at Trirand.Web.Mvc.JQGrid.DataBind(Object dataSource)
at Cormant.OrangeReports.Web.Controllers.ResourcePlanningController.FilterData(Nullable`1 customerID, Nullable`1 projectID, Nullable`1 startDate, Nullable`1 endDate, String employeeID) in e:\Projects\OrangeReports\Cormant.OrangeReports.Web\Controllers\ResourcePlanningController.cs:line 175
Thanks in Advance

Cannot trace the error source when parsing an XML file

This is the code:
var serializer = new DataContractSerializer(typeof(QuoteAndOfferCollection));
try
{
using (var file = File.OpenRead(filename))
{
offers = (QuoteAndOfferCollection)serializer.ReadObject(file);
}
}
catch (SerializationException sex)
{
File.AppendAllText(log, "Deserialization failed - " + sex);
return;
}
And this is the error I get:
xmlDeserialization failed - System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type Services.Dto2.QuoteAndOfferCollection. The value '' cannot be parsed as the type 'Int32'. ---> System.Xml.XmlException: The value '' cannot be parsed as the type 'Int32'. ---> System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Xml.XmlConvert.ToInt32(String s)
at System.Xml.XmlConverter.ToInt32(String value)
I am not able to trace the '' part.
Catch the exception and get the value of file.Position. That will give you some idea of where in the file the offending line is. You can do better than that if you wrap a custom stream around the FileStream and keep track of the number of lines read.
You might also be able to create an XmlReader, and pass that to ReadObject. When you catch the exception, examine the reader's properties. It might tell you exactly what line had the error.
But you'll need move where the exception is caught. That is, rather than:
try
{
using (stream)
{
// deserialize
}
}
catch
{
}
you want to write:
using (stream)
{
try
{
// deserialize
}
catch
{
}
}

Why is CSharpOptParse UsageBuilder failing due to an XPathException only when used in an NUnit test?

What is the root cause of this issue? CSharpOptParse, XslTransform.Transform(...), or NUnit? What other equivalent library could I use instead, if this problem is unfixable, that is being actively supported?
I'm using version 1.0.1 of CSharpOptParse which was last modified in Feb 2005.
I've have the following class (simplified for this example of course) to use along with CSharpOptParse:
public enum CommandType
{
Usage
}
public class Options
{
[OptDef(OptValType.Flag)]
[LongOptionName("help")]
[Description("Displays this help")]
public bool Help { get; set; }
public CommandType CommandType
{
get { return CommandType.Usage; }
}
}
Here is a bit of unit test code that replicates the issue:
TextWriter output = Console.Out;
Options options = new Options { Help = true };
Parser p = ParserFactory.BuildParser(options);
p.Parse();
output.WriteLine("Usage: Console [--a]");
UsageBuilder builder = new UsageBuilder();
builder.BeginSection("Arguments:");
builder.AddOptions(p.GetOptionDefinitions()); //could the issue be created here?
builder.EndSection();
builder.ToText(output, OptStyle.Unix, true); //The problem occurs here
Is it possible that I'm causing the problem by not setting up the UsageBuilder with the correct sections? Possibly this might be causing problems in the xslt file???
When I run that code I get the following exception:
System.Xml.XPath.XPathException : Function 'ext:FormatText()' has failed.
----> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
----> System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: startIndex
at MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator)
at System.Xml.Xsl.XsltOld.Processor.ValueOf(ActionFrame context, Int32 key)
at System.Xml.Xsl.XsltOld.ValueOfAction.Execute(Processor processor, ActionFrame frame)
at System.Xml.Xsl.XsltOld.ActionFrame.Execute(Processor processor)
at System.Xml.Xsl.XsltOld.Processor.Execute()
at System.Xml.Xsl.XsltOld.Processor.Execute(TextWriter writer)
at System.Xml.Xsl.XslTransform.Transform(XPathNavigator input, XsltArgumentList args, TextWriter output, XmlResolver resolver)
at System.Xml.Xsl.XslTransform.Transform(IXPathNavigable input, XsltArgumentList args, TextWriter output, XmlResolver resolver)
at CommandLine.OptParse.UsageBuilder.ToText(TextWriter writer, OptStyle optStyle, Boolean includeDefaultValues, Int32 maxColumns)
--TargetInvocationException
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at System.Xml.Xsl.XsltOld.XsltCompileContext.FuncExtension.Invoke(XsltContext xsltContext, Object[] args, XPathNavigator docContext)
at MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator)
--ArgumentOutOfRangeException
at System.String.LastIndexOfAny(Char[] anyOf, Int32 startIndex, Int32 count)
I have no idea what is causing this problem....and the weirdest part is that is only occurs within my NUnit test. When this code is called via "Console.exe --help" it runs fine with no exceptions. I can't see anything wrong with CSharpOptParse so could this be a problem in .NET's XslTransform class or in NUnit?
Has anyone else experienced this issue? Does anyone have any advice on how to track down the issue or switch to a better library?
I know this is an old question. But..
The exception is caused because the ToText() method tries to determine the width of the console and it fails when you're writing to anything that is not a real console.
The fix is simple: Set a fixed width.
Change the call to ToText to:
try
{
usage.ToText(Console.Out, OptStyle.Unix, true);
}
catch
{
usage.ToText(Console.Out, OptStyle.Unix, true, 90);
}
Now if the normal call fails, it will try a fail-safe one.
Why don't you attach a debugger to NUnit, turn on First-Chance exceptions, and find out what's going on?
I ran into the same issue and have seemed to have fixed it (not sure of the issues it would cause doing this but everything seems to work okay).
Find:
public TextTransformHelper(int maxColumns)
{
_maxColumns = maxColumns;
if (_maxColumns == -1)
{
// try to determine console width
string os = Environment.GetEnvironmentVariable("OS");
if (os != null && os.StartsWith("Win"))
{
ConsoleUtils.ConsoleHelper ch = new ConsoleUtils.ConsoleHelper();
_maxColumns = ch.GetScreenInfo().Size.X;
}
}
}
and then modify it to the following:
public TextTransformHelper(int maxColumns)
{
_maxColumns = maxColumns;
if (_maxColumns == -1)
{
// try to determine console width
string os = Environment.GetEnvironmentVariable("OS");
if (os != null && os.StartsWith("Win"))
{
ConsoleUtils.ConsoleHelper ch = new ConsoleUtils.ConsoleHelper();
_maxColumns = ch.GetScreenInfo().Size.X;
if(_maxColumns == 0) //added
_maxColumns = -1; //added
}
}
}
The reason it was blowing up was because in the FormatText function it has the following if statement which was supposed to be hit if a columnwidth was not defined or was -1. The function for me would always return 0 which would cause the below if statement to not get hit and then cause an "ArgumentOutOfRange" exception. This was on Windows Server 2008:
if (_maxColumns == -1)
{
output.Append((first) ? indentStr : handingIndentStr);
output.Append(line);
output.Append(Environment.NewLine);
first = false;
continue;
}
I was able to debug it by seeing the "ext:FormatText" failed error and then setting breakpoints on all FormatText functions (the xslt was calling the C# function) and then looking at the exception and debugging in further.
I hope this helps.
John Rennemeyer

Categories

Resources