Tag: com

为什么Excel的com对象不会从内存释放,如果我检查它为null?

我已经inheritance了一个现有的应用程序来维护并遇到一个问题:一旦完成,它不会从内存中释放Excel对象。 我已经在这里提出了相关的代码。 这是一种使用COM Interop创buildExcel工作簿的方法: using System.Runtime.InteropServices; using Excel = Microsoft.Office.Interop.Excel; … private void CreateWorkbook(string workingDirectory, string fileName, object[,] cellValues) { Excel.Application excel = null; Excel.Workbooks workbooks = null; Excel.Workbook workbook = null; Excel.Sheets worksheets = null; Excel.Worksheet worksheet = null; Excel.Range startRange = null; Excel.Range endRange = null; Excel.Range selectedRange = null; try { excel […]

正确的方法来检测如果Excel已经退出,并作出适当的回应?

我有一个Windows窗体应用程序,打开一个Excel的实例。 如果用户提前退出应用程序,我想确保这个Excel实例已经退出。 我试着调用Excel实例的Quit()方法,如果实例不为null ,就像这样: static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Form1 form1 = new Form1(); Application.Run(form1); form1.logFile.close(); if (form1.xlApp != null) { form1.xlApp.Quit(); } } } 但是,如果我退出任务pipe理器中的Excel应用程序,然后closuresGUI,我得到这个错误: System.Runtime.InteropServices.COMException (0x800706BA): The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) 即时窗口中的(xlApp==null)检查显示xlApp不为null,即使没有运行Excel的实例。 所以我尝试删除Quit()行,并使用它来代替: Marshal.ReleaseComObject(form1.xlApp); 当用户尽早退出Excel应用程序时,此工作正常无错地closures,但如果GUIclosures时该实例仍在任务pipe理器中运行,则ReleaseComObject()调用不会结束Excel实例。

为什么ITypeInfo :: GetIDsOfNames不工作?

我正在修改COM自动化的一些代码。 使用Excel(应用程序)的IDispatch客户端,我可以评估 idispatch.GetIDsOfNames('Run' 'Macro' 'Arg1' 'Arg2') 它的工作。 它返回一个数组,其中包含Run的方法(本版本中为1925)的成员ID和参数Macro,Arg1和Arg2的索引。 但是,如果我试图从ITypeInfo获得相同的信息,我得到发送GetTypeInfo(0)到相同的idispatch,它会产生错误HRESULT_E_NOTIMPL。 这个函数在ITypeInfo上工作吗? 文件说是…

无法在Application.Run上debuggingSystem.Runtime.InteropServices.COMException

我有一个Excel函数,我从C#调用如下: string result = xlApp.Run("'ExcelBook.xlsm'!mainFromBatch", "http://someSite/TestFile.xlsm", false, "T:\\somePath"); 运行时会产生一个错误: An exception of type 'System.Runtime.InteropServices.COMException' occurred in BatchConverter.exe but was not handled in user code Additional information: Exception from HRESULT: 0x800ADF09 If there is a handler for this exception, the program may be safely continued. mainFromBatch的函数头是: Function mainFromBatch(sourceBkPath As String, Flag As Boolean, _ Optional outputPathFromConfig […]

使用Windows Installer部署COM加载项的困难

我在Visual Studio 2012中创build了一个COM加载项,当我在我的机器上编译和运行它时,它完美地工作。 当我尝试使用我创build的Windows安装程序来安装加载项时出现问题。 我正在尝试将这个加载项安装到多台机器上,我想知道问题出在安装程序上。 当我尝试使用Excel调用COM加载项的Sub时,它会在第二行引发“下标超出范围”。 Sub连接到SQL服务器,根据单元数据执行查询,并返回结果。 我在Excel中查看加载项,它已安装,并且不处于不活动状态/禁用状态。 如果我在我的机器上编译项目,这个相同的代码完美的工作,而不是当我用安装程序安装加载项。 Dim com as COMAddIn Set com = Application.COMAddIns("SQL") <—- com.Object.ConStr 我按照这个指导安装程序: https://msdn.microsoft.com/en-us/library/Cc442767.aspx 我做了以下的安装程序运行(只是上面的文章的摘要): 将主输出,.vsto和dll.manifest文件添加到应用程序文件 添加了.NET Framework 4.5(完整版)和Visual Studio 2010 Tools for Office Runtime作为先决条件 设置INSTALLDIR 指定应用程序应该部署到当前用户 告诉安装程序创build以下registrypath HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins\JACOB.SQL 创build了以下registry项 Description SQL FriendlyName SQL LoadBehavior 3 Manifest file:///[INSTALLDIR]SQL.vsto|vstolocal 将生成设置为SingleImage 将InstallShield先决条件设置为“从Web下载” 将活动解决schemeconfiguration设置为SingleImage 将安装程序的configuration设置为SingleImage build立安装程序 我确保从Excel中卸载我的项目的编译版本,然后转到以下文件path并运行setup.exe。 %Visual Studio 2012%\Projects\SQL\Setup1\SQL_Setup\Express\SingleImage\ DiskImages\DISK1 […]

当Application.Visible为false时,间歇性错误0x800A03EC

我在C#中使用Excel进行互操作,遇到了一个我无法弄清楚的奇怪的错误。 我一直在做这个错误的大量阅读,你可能会注意到这篇文章的标题是非常类似于间歇HRESULT:0x800A03EC错误在Excel的SaveAs在.NET 2.0应用程序 。 这个问题是不一样的。 我有的错误是间歇性的, 但有一些疯狂的方法。 我只是无法弄清楚这个方法是什么。 当我尝试执行这样的一行时,我得到错误0x800A03EC ,恰好在我将副本保存到networking后发生: someExcelWorksheet.getRange("MyNamedRange").Value = "new value"; 我知道这是一个令人厌恶的错误,其原因很难缩小。 这是Hans Passant对第一段中提到的问题的评论。 当Excel因为忙于完成其他工作而感到不安时,就会发生这种情况。 当你有一台更快的机器时,可能会发生,让你更难以掌握Excel。 很难处理。 这里有一个有趣的部分:只有当Excel应用程序不可见并且使用Wi-Fi时才会发生。 以下是四个用于澄清的用例: 100%成功:以太网( app.Visible = true;下, app.Visible = true;上)+ app.Visible = true; 100%成功:以太网( app.Visible = false;下, app.Visible = false;上)+ app.Visible = false; 100%成功: Wi-Fi( app.Visible = true;下, app.Visible = true;上)+ app.Visible = true; 成功30%: Wi-Fi( […]

从Excel中读取interop并将不同的值写入另一个工作表

我正在使用C#4.0,并从一个Excel表中读取,并从每个列中获取值,然后在另一个表上,我正在写每列不同的值。 即如果结果表具有: COLA COLB COLC —– ——- ——- dog cow rabbit cat moose hare dog moose bunny bird yak hare fish fox bunny weasel fox bunny 那么不同的表应该有(在每一列内sorting并不重要): COLA COLB COLC —– ——- ——- dog cow rabbit cat moose hare bird yak weasel fish fox bunny 任何人都可以提出一个更简单的方法(仍然使用COM Interop的Excel)否定需要使用这个丑恶的二维对象数组,ArrayList,列表回到array.etc。 这是我正在编写的代码,感觉就像我走错了方向: for (int c = 0; c < […]

Excel文件中的ActiveX控件在某些机器上给出“无法加载对象…”错误

我们在公司的几台机器上使用一组Excel文件。 这些文件包含一个VBA应用程序,它利用来自mscomct2.ocx库(即MonthView和DateTimePicker )的一对ActiveX控件对象。 ActiveX对象将在UserForm中显示。 不幸的是,这些文件的可移植性似乎受限于一个非常奇怪的方式。 似乎有两组机器: A组:我可以在这样的机器上创build一个包含MonthView的Excel文件,并在任何A组PC上使用它。 但是,当我尝试在组B的任何一台机器上打开这个文件,我得到一个无法加载一个对象,因为它不是在这个机器上的错误。 但是,在B组机器上创build的具有相同ActiveX的文件在A机器上正常工作。 B组:带有在这些机器上创build的ActiveX的文件在任何地方都可以工作(即在任何A和B机器上)。 但是,正如我前面所说的,当机器上保存的ActiveX文件打开时,B机器给出上述错误。 在一个句子中: 在一台机器上创build的文件只能在其他A上工作,无处不在B上创build的文件 ! 这里最奇怪的是每台机器都有mscomct2.ocx注册(再一次:我可以在任何机器上使用MonthView创build表单)。 .ocx本身就位于每台机器上,并且存在整套registry项(CLSID用于控件类,IID,typelib ID …)。 此外,这些registry项中的数据在A和B组机器上(GUID,ProgID,版本等)似乎是相同的。 在某些机器上,描述string(如“Microsoft MonthView Control 6.0(SP6)”的值)略有不同,但这似乎并不影响这种情况(B组中的一些机器具有不同的描述,但在其上创build的文件仍然可用)。 当然,由于墨菲定律,我用来编辑这些Excel文件的机器属于A组,所以这里保存的文件对B机器是“不可移植的”。 操作系统和Excel版本似乎不影响这种情况。 例如,B机器中的一个在Win 7 64位(Excel 2007)下工作,而大多数其他组A和B机器是Win XP Prof(32位)SP3,安装了Excel 2003。 所以看来,操作系统和Excel版本不会影响兼容性,并且问题与ActiveX有关。 我发现A和B组之间唯一与ActiveX相关的区别是mscomct2.ocx的文件版本:A机器中至less有几个版本是6.1.xx,而B组是6.0.xx我看不出有什么区别导致问题(毕竟ActiveX是COM对象,并且根据registry键值,暴露的typelib,com对象和接口在所有情况下似乎是相同的)。 尽pipe如此,我试图用6.0.xx版本取代我的6.1.xx ocx ,并且遇到了更多麻烦。 我所做的是: regsvr32 /u mscomct2.ocx – 已成功完成 用6.0.xx版本的文件replace了mscomct2.ocx regsvr32 mscomct2.ocx – 已成功完成 完成这些步骤之后,我尝试使用包含MonthView单个窗体创build一个Excel文件。 但是当我试图放置一个控件的forms,我有一个错误类没有注册的消息框。 这真是奇怪,因为一切似乎都被注册了:控制类,它的接口,typelib(是的,我已经检查过registry)。 但仍然有错误。 之后,我再次取消注册/replace/注册过程回到我原来的6.1.xx文件。 这使我回到原来的SNAFU情况:我可以再次安装ActiveX到用户窗体并使用它,但B组机器仍然给我的机器保存的文件上的错误。 我认为文件与ActiveX可移植性的问题和ocx注册的问题以某种方式连接,但我不知道如何。 […]

读取Excel单元格并设置行颜色

我正在使用Com Interop和C#。 我必须遍历一个Excel文件,在每个行中查找特定的值(总是在第2列)。 对于某些值,我需要将该行的背景颜色设置为红色。 我有麻烦: 读取单元格[i] [2]中第i行的值 设置该行的背景颜色。 基本上我正在寻找这样的东西(这是我可以find最好的谷歌search之后): // ws is the worksheet for (int i = 1; i <= ws.Rows.Count; i++) { Range range = ws.Cells[i][2]; int count = Convert.ToInt32(range.Value2.ToString()); if (count >= 3) { Range chronic = ws.UsedRange.Rows[i]; chronic.EntireRow.Cells.Interior.Color = 0xFF0000; } } 当然这不起作用。 我无法摆脱阅读牢房的第一个障碍。 任何意见表示赞赏。

如何可靠地确定文件是否已在Microsoft Excel中打开?

我正在实现一个接口到Excel。 我正在使用COM来直接从C ++自动化Excel。 我的大部分应用程序工作可靠。 但是,我不能检测文件是否已经在Excel中打开。 如果它是开放的,那么我想通知用户在运行模拟之前closures它。 我不使用MFC,VB或.NET。 我的解决scheme必须为Excel版本97至2010年工作。如果我可以以编程方式知道Excel的版本,可以使用不同的技术为不同的Excel版本。 我在同一个文件夹中查找名称为“〜$ xxx”(其中“xxx”是原始文件名)的文件,以确定Excel是否创build了会话锁。 但是这种技术并不总是有效。 一个类似的问题是一旦模拟开始在我的程序中,我想阻止用户在写入模式下打开文件(只读模式是OK)。