有没有办法以编程方式检索与C#一起使用的Excel Interop库的版本?
我知道我可能会在注册表中查找已安装的Microsoft Office实例,但我很好奇Excel库是否包含此信息.
我知道当您引用库时,此信息包含在Visual Studio中,但我无法在运行时看到该信息.
我问这个是因为它在您保存工作簿时指示文件扩展名,如果您使用".xls"保存2007工作簿,则2007抱怨扩展名不正确.
简短的回答是:您不需要知道加载哪个PIA版本来解决您的问题.您想知道的是实际运行的是哪个版本的Excel.虽然运行的Excel版本和PIA版本通常是相同的,但它们不一定是,并且在这种情况下,它是您关心的Excel版本,而不是PIA版本.
确定正在运行的Excel版本并不难,但它不是那么容易,因为该Excel.Application.Version属性可以返回诸如"11.0"或"9.0a"之类的字符串,因此不一定能直接将其解析为整数值.您可以依赖于小数点左侧的所有内容(".")都是版本号的事实,因此以下代码适用于所有版本:
Excel.Application excelApp = new Excel.Application();
string versionName = excelApp.Version;
int length = versionName.IndexOf('.');
versionName = versionName.Substring(0, length);
// int.parse needs to be done using US Culture.
int versionNumber = int.Parse(versionName, CultureInfo.GetCultureInfo("en-US"));
if (versionNumber >= 12)
{
// Excel 2007 or above.
}
else
{
// Excel 2003 or below.
}
Run Code Online (Sandbox Code Playgroud)
至于PIA与Excel对象模型问题,您的程序集在开发时引用的主Interop程序集(PIA)与在目标计算机上实际加载PIA的程序可能不同.例如,如果您引用Excel 2002 PIA并且目标计算机使用Excel 2007,那么(通常)将加载Excel 2007 PIA.规则是目标计算机上可用的最高版本的Office PIA在运行时加载.
它变得更加复杂,因为目标机器有可能(尽管,绝对不可能),例如,Excel 2007加载到目标机器上,但最高可用的PIA适用于Excel 2003.在这种情况下,Excel 2007将加载,但您的代码将针对Excel 2003 PIA.反过来也可能发生:Excel 2007 PIA可用,但机器上安装的最高实际版本是Excel 2003 - 在这种情况下Excel 2003将加载,但您的代码将对Excel 2007 PIA起作用.
在标准设置中,这些情况不太可能发生.最有可能发生在开发人员的机器上,其中(1)机器上同时存在多个Excel版本,或者(2)已添加和删除了Excel版本,但PIA未随其删除(这本身也不太可能,因为我认为PIA是自动卸载的,但我可能错了.)
有关这方面的更多信息,请参阅Andrew Whitechapel的文章为什么多个版本的Office不支持VS开发?
虽然所有这些场景听起来有点可怕,但Excel对象模型中的接口非常一致,因此几乎100%向后兼容.通常,如果绑定到给定的Excel PIA版本,那么您的代码将针对该版本的Excel或更高版本成功运行,几乎与所涉及的scenio无关.然而,正如您所发现的那样,有一些怪癖,但关键是要知道实际运行的是哪个Excel版本.知道哪个PIA正在运行通常不重要 - 只要您针对(或更高)开发的PIA版本可用,那么PIA本身不应该引起任何问题.
编辑:跟进phsr的评论:
当我保存我生成的工作簿时,我确实需要知道我正在使用的PIA,因为它将以该格式保存.如果我得到PIA的版本,我可以给文件名正确的扩展名("xls"vs"xlsx").即使将2007工作簿保存为"xls",它也会发出与文件扩展名指定的格式不同的警告.我想通过使用正确的扩展名隐藏该警告.你的观点是正确的,因为它最终无关紧要(文件仍然会打开),但在某些情况下(如这一个)它确实如此.
我知道它可能"感觉"是PIA的问题,但是实际加载的Excel对象模型在这里很重要,而不是PIA.此外,Excel应用程序版本号与PIA版本相同的可能性为99.9%.他们会有所不同是非常罕见的.如果它们有所不同,则重要的是Excel版本,而不是PIA(只要PIA与您开发的PIA版本相同或更高).
为了澄清这一点,PIA仅指定所涉及的接口,而不是功能.在Excel 2003中另存为方法具有完全相同的参数签名的Excel 2007中另存为方法,所以PIA的这里不相同.SaveAs但是,如何执行该方法取决于实际运行的Excel对象模型的版本.
为了解决您的问题,我建议您采取以下两种可能的行动方案之一:
(1)尝试上面给出的代码来确定正在运行的Excel版本.如果你这样做并相应地调整你的代码它会起作用,我保证.如果失败,请显示您的代码,我相信我们可以让它运行起来.
(2)不要在您提供的工作簿名称中指定扩展名.让Excel应用程序为您添加默认扩展名.你是正确的,如果你在Excel 2007中保存时指定了".xls"扩展名,它将尊重该扩展名,但不尊重工作簿版本.但是,最简单的方法是在保存工作簿时省略扩展名,Excel应用程序会自动将".xls"或".xlsx"附加到工作簿名称,具体取决于当前运行的Excel版本:
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = excelApp.Workbooks.Add(Type.Missing);
workbook.SaveAs(
"MyWorkbook", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Run Code Online (Sandbox Code Playgroud)
上面的结果是一个名为"MyWorkbook.xls"或"MyWorkbook.xlsx"的工作簿,具体取决于正在运行的Excel版本.简而言之,让Excel为您完成工作,这样您就不必担心它.
| 归档时间: |
|
| 查看次数: |
5386 次 |
| 最近记录: |