Nov 9

C#中用如下代码输出Grid到Excel,

C# Code Copy Code To Clipboard
  1. public static Microsoft.Office.Interop.Excel.Application _excelobj = new Microsoft.Office.Interop.Excel.Application();  
  2.   
  3. public static Workbook _newbook = _excelobj.Workbooks.Add();  
  4.   
  5. ////...  
  6.   
  7. Microsoft.Office.Interop.Excel.Worksheet _newsheet = _newbook.ActiveSheet;   

在输出后如果关闭了Excel再调用输出,会在上面第7行出现错误 :

The object invoked has disconnected from its clients. (Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED))

究其原因,就是因为excel关闭以后,_newbook这个object不存在了。所以,在第7句前加一个判断即可解决:

C# Code Copy Code To Clipboard
  1. if (_excelobj.ActiveWorkbook == null)  
  2. {  
  3.      _newbook = _excelobj.Workbooks.Add();  
  4. }  
  5.   
  6. Microsoft.Office.Interop.Excel.Worksheet _newsheet = _newbook.ActiveSheet;   

 

Tags: , , , ,
May 7

Installshield做的安装文件在XP测试机上出现Error 1001错误.InstallUtilLib.dll: Unknown error.

原因是XP测试机上没有.NET 4.0而只有.NET 2.0.安装前检测可以避免这种错误但是有这限制不好.因为用不上.NET4.0. 在Installshield的toolsoptions菜单里改一下.NET的选项,原来.NET Framework File的location默认是4.0的,改成用2.0的就可以了.(下图是已经改成2.0的了)

 

Nov 19

这个BUG是老早就存在的,在我刚来公司没多久的时候,JACK就跟我说起过这个问题,这个问题的症状很奇怪,正常使用时,它永远不会出现,而当用户把屏幕锁定以后再过若干时间,就会有一长串的弹出窗口,更怪的是,这些窗口有时有,有时没有.

 

同事最近老是遇上这个问题,要我一定得想想办法,凑了点时间仔细查看了这个问题,发现如下的细节:

  • 这个错误出现的前提是: 1. 屏幕锁定, 2. 屏保出现
  • 程序的窗口需要是当前窗口,如果仅在后台运行,这个错误不会出现
  • 即使是在当前窗口,这个错误也不是每次都会出现,似乎与当前子窗口有关
  • 即使是相同子窗口,这个错误也是有时出现,有时不出现
  • 根据经验判断应该是定时器中出现的问题
  • 这个错误其实包括2个, 1. "A call to an OS function failed.", 2. "Access denied" 错误

由于这个错误只在屏幕锁定且有屏保时出现,我先把计算机的屏保设定为1分钟,以减少浪费的时间,然后用DELPHI打开工程进入DEBUG模式启动程序,再锁上屏幕等屏保出现.如果有效,那么出错时DELPHI应该截获这个出错信息并停留在那里.

1分钟以后,输入密码重新进入桌面,果然,DELPHI报错了,可是,错误的地方不是我的程序,而是进入了Forms.pas这个系统单元,在function TApplication.ProcessMessage这个函数中,停留在这句 TranslateMessage(Msg); 上.

按F8进行DEBUG,进入了ExtCtrls这个系统单元,原来是这里出的错,上面的函数是在 Application.HandleException(Self); 这里调用到的.继续F8,我的程序跳出了错误框,然后就结束了.没有找到哪里出错.不过,这也验证了的确是定时器的问题,但是,是哪个定时器呢?

我把主界面及子窗口中的所有定时器全部关闭,可是这个错误还是照常出现.奇怪了.

procedure TTimer.WndProc的定义如下:

Copy Code To Clipboard
  1. procedure TTimer.WndProc(var Msg: TMessage);
  2. begin
  3. with Msg do
  4. if Msg = WM_TIMER then
  5. try
  6. Timer;
  7. except
  8. Application.HandleException(Self);
  9. end
  10. else
  11. Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
  12. end;

我把断点设在第6行 Timer上,用F7不断进行跟踪,跳转了几次后,发现进入了一个自定义的控件单元,有戏!

进入的函数是OnHintTimer. 看,这就是一个隐藏的TIMER不是.我在这个函数的开始加个EXIT使之禁用,再运行程序,锁屏,等屏保,再进入.果然没有错误了!看来问题就是在这儿.

程序函数中出错的地方居然是取鼠标位置的几句,很奇怪会出这样的错误.我又试了一下,恢复原来的代码,使当前窗口是此程序,如果把鼠标移到此程序窗口之外,再锁屏,等屏保,解锁再进入,果然就是没有错误的.

再次尝试,把出错的一段句子加上try...except....语句.在except中加上Mouse.CursorPos.x,结果...居然就没有错,晕死.

总结一下这个错误:当打开此程序,并激活某个使用特定控件的窗口,使此控件的OnHintTimer可用,并且鼠标指针在此控件上,能引发OnHintTimer事件.在这种情况下,锁定屏幕,使计算机进入屏保(如果不锁屏,只进入屏保也不会引发这个错误),然后再解除屏幕锁定,就会在此控件的OnHintTimer事件中发生错误,而发生的错误是在获得鼠标位置的语句.错误为"A call to an OS function failed.",由系统抛出.

老实说,这个错误非常奇怪,因为在OnHintTimer中只是获得鼠标位置,我甚至已经把此事件中的语句删得仅剩一句
x :=Mouse.CursorPos.x;
了.也还是一样的错误.到底为什么,还是一个谜,我会继续追踪下去.

无论如何,这个错误是找到了,要解决的话,只要在OnHintTimer事件中套上try...except...end语句,那么就不会出现那些烦人的错误框了.

Tags: , , , , , , , , , ,
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]