2009-08-31 2 views
3

Есть ли способ программно получить версию библиотек Excel Interop, используемых с C#?Извлечение версии библиотеки Excel Programmatically

Я знаю, что, возможно, я мог бы посмотреть в реестре, чтобы выяснить установленный экземпляр Microsoft Office, но мне было любопытно, содержат ли библиотеки Excel эту информацию.

Я знаю, что эта информация содержится в Visual Studio, когда вы ссылаетесь на библиотеку, но я не вижу эту информацию во время выполнения.

Я спрашиваю об этом, потому что он диктует расширение файла при сохранении книги, и если вы сохраняете книгу 2007 года с «.xls», 2007 жалуется на неправильное расширение.

ответ

7

Короткий ответ: вам не нужно знать, какая версия 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. 
} 

Что касается PIA против Excel проблема с объектной моделью, с которой связана сборка первичной вставки (PIA) при сборке, когда PIA фактически загружается во время выполнения на целевой машине, может быть разной. Например, если вы ссылаетесь на PIA Excel 2002, а целевая машина использует Excel 2007, тогда (как правило) загружаются PIA Excel 2007. Правило заключается в том, что высокопроизводительный Office PIA, доступный на целевой машине, загружается во время выполнения.

Это становится еще более сложным в том, что возможно (хотя и не обязательно) для целевой машины иметь, скажем, Excel 2007, загруженный на целевую машину, но самые высокодоступные PIA для Excel 2003. В этот случай, Excel 2007 будет загружаться, но ваш код будет работать против PIA Excel 2003. Также может произойти обратное: доступны PIA Excel 2007, но самая высокая фактическая версия, установленная на компьютере, - Excel 2003 - в этом случае Excel 2003 будет загружаться, но ваш код будет работать против PIA Excel 2007.

Эти сценарии очень маловероятны в стандартной настройке. Скорее всего, это происходит на машине разработчика, где одновременно (1) присутствует более одной версии Excel, или (2) версии Excel были добавлены и удалены, но PIA не удалены с ней (что само по себе также маловероятно, так как я считаю, что PIA автоматически удаляются, но я могу ошибаться в этом).

Более подробно об этом см статьи Эндрю Whitechapel в Why is VS development not supported with multiple versions of Office?

Хотя все эти сценарии звучат немного страшновато, интерфейсы в объектной модели Excel являются чрезвычайно последовательны и, следовательно, почти 100% обратной совместимостью. В общем случае, если вы привязаны к данной версии Excel PIA, ваш код будет успешно работать с этой версией Excel или выше, в значительной степени независимо от сценария. Хотя, как вы уже выяснили, есть несколько причуд, но ключ должен знать, какая версия Excel действительно работает. Знание того, что работает PIA, обычно не имеет значения - если версия PIA, разработанная против (или выше), доступна, то сам PIA не должен вызывать никаких проблем.

Edit: Развейте на комментарий phsr в:

Когда я спасая Workbook Я генерировать, я должен знать, что PIA я работает против, потому что это будет сохранено в этот формат. Если я получу версию PIA , я могу указать имя файла для исправления расширения («xls» против «xlsx»). Даже если рабочая книга 2007 года сохранена как «xls», она даст предупреждение о другом формате , чем указано расширением файла. Я бы хотел скрыть это предупреждение от , используя правильное расширение. Ваш указывает на то, что он действительно не имеет значения в конце (файл по-прежнему будет открыт), но в некоторых случаях экземпляров (например, этот).

Я знаю, что он может «чувствовать себя», это проблема PIA, но это объектная модель Excel, которая действительно загружена, что имеет значение здесь, а не PIA. Кроме того, существует вероятность 99,9% того, что номер версии приложения Excel является ТОЛЬКО как версия PIA. Чрезвычайно редко, что они будут отличаться. И там, где они отличаются друг от друга, важна версия Excel, а не PIA (пока PIA будет той же версией, что и PIA, которую вы разработали против или выше).

Чтобы прояснить это, PIA указали только связанные интерфейсы, а не функциональность. Excel 2003 SaveAs method имеет точно такую ​​же сигнатуру параметра, что и Excel 2007 SaveAs method, поэтому PIA здесь не отличаются. Однако, как работает метод SaveAs, зависит от того, какая версия объектной модели Excel фактически работает.

Чтобы устранить проблему, я могу предположить, принимая одну из двух возможных направлений действий:

(1) Попробуйте код, который я дал выше, чтобы определить версию Excel, на котором выполняется. Если вы это сделаете и настройте свой код соответственно, это сработает, я обещаю. Если это не удается, покажите свой код, и я уверен, что мы можем заставить его работать.

(2) Не указывайте расширение в названии книги, которое вы ему даете. Пусть приложение Excel добавит для вас расширение по умолчанию. Вы правы в том, что если вы укажете расширение «.xls» при сохранении в Excel 2007, оно будет уважать это расширение, но не версию рабочей книги. Однако проще всего просто опустить расширение при сохранении вашей книги, и приложение 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); 

В результате вышеперечисленное учебное пособие называется либо„MyWorkbook.xls“или„MyWorkbook.xlsx“, в зависимости от того, какой вариант Excel работает Короче говоря, пусть Excel сделать работу за вас, так что вам не придется беспокоиться об этом

+0

Когда я сохраняю Рабочую книгу, которую я сгенерирую, мне нужно знать, с чем я работаю PIA, потому что она будет сохранена в этом формате. Если я получу версию PIA, я могу указать имя файла для исправления расширения («xls» vs «xlsx»). Даже если книга 2007 года сохраняется как «xls», она будет предупреждать о том, что она отличается от формата, указанного в расширении файла. Я хотел бы скрыть это предупреждение, используя правильное расширение. Ваша точка верна в том, что она действительно не имеет значения в конце (файл все равно будет открыт), но в некоторых случаях (например, этот). –

+0

Это действительно версия Excel, которая работает, что вам нужно беспокоиться здесь, а не версия PIA, честная. Обещаю. См. Мое обновление выше, в разделе «Редактировать: следить за комментариями phsr». –

2

Я думаю, что реестр окон является хорошим источником информации в этом отношении. Определите соответствующие ключи и получите их значения во время выполнения.

Этот код может быть вдохновляющим:

Getting the office version

+0

Я знаю, что я мог бы получить его из реестра, но я искал другую путь. +1 для примера кода, спасибо. –

0

Попробуйте (исходный код): ExcelDna..

разместите этот код где-то в классе декларация:

[DllImport("XLCALL32.DLL")] 
public static extern int XLCallVer(); 

Вызов этой функции, где вам нужно:

int version = XLCallVer()/256; 

Или, если вы используете ExcelDna вы можете позвонить directry:

double version = ExcelDnaUtil.ExcelVersion; 
Смежные вопросы