title: Determine which version of Excel was used to create a .xls or .xlsx
body: <p>I'm about to write an application to start .xls, .xlsx and .xlsm with the version of Excel used to create these files.
  The reason is that they contain a lot of VBA scripts that work differently in different versions of Excel (thanks to Microsoft!).
  I'm searching for a way to determine the version used to create such a file.</p>
  
  <p>I have tried latebinding Excel and reading the <code>CalculationVersion</code> property but this shows me only the last version used to edit the file. Same for the version number in app.xml inside an .xlsx. It also seems the marker in the binary of the file is changing after editing and saving the file, though I am not sure all these markers change.</p>
  
  <p>Does anyone know a marker or property which gives the version which <em>created</em> the file?  </p>
  
  <p>Please answer also if it works only for .xls or only for .xlsx. This will bring me a bit closer to my target. </p>
  
  <p>Edit: to get the calculation version:</p>
  
  <pre><code>  private string CalculationVersion()
  
      {   //Variablen
  
          string version = String.Empty;
  
          object Object_Excel_Application = null;
  
          object Object_WorkBooks = null;
  
          object Object_WorkBook = null;
  
          object[] Parameters;
  
          Type Type_of_Programm;
  
  
  
          //Typ der Excel.Application bestimmen
  
          Type_of_Programm = Type.GetTypeFromProgID("Excel.Application");
  
  
  
          //Eine Excel instanz erstellen und in Object_Excel_Application speichern
  
          Object_Excel_Application = Activator.CreateInstance(Type_of_Programm);
  
  
  
          try //Versuche
  
          {
  
              //Excel unsichtbar machen
  
              Parameters = new Object[1];
  
              Parameters[0] = 0;
  
              Object_Excel_Application.GetType().InvokeMember("Visible", BindingFlags.SetProperty, null, Object_Excel_Application, Parameters);
  
  
  
              //Interaktion mit dem User unterbinden
  
              Parameters = new Object[1];
  
              Parameters[0] = 0;
  
              Object_Excel_Application.GetType().InvokeMember("Interactive", BindingFlags.SetProperty, null, Object_Excel_Application, Parameters);
  
  
  
              //Workbooks erstellen
  
              Object_WorkBooks = Object_Excel_Application.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, Object_Excel_Application, null);
  
  
  
              //Die angegebene Datei öffnen
  
              Parameters = new Object[15];
  
              Parameters[0] = dateiPfad;
  
              for(int i = 1; i &lt;= 13; i++)
  
              {
  
                  Parameters[i] = Missing.Value;
  
              }
  
              Parameters[14] = true;
  
              Object_WorkBook = Object_WorkBooks.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, Object_WorkBooks, Parameters);
  
  
  
              //Letzte Calculations Version auslesen
  
              version = Object_WorkBook.GetType().InvokeMember("CalculationVersion", BindingFlags.GetProperty, null, Object_WorkBook, null).ToString();
  
              MessageBox.Show(version);
  
  
  
              //Wieder schließen
  
              //Workbook zumachen
  
              Parameters = new Object[3];
  
              Parameters[0] = true;
  
              Parameters[1] = Missing.Value;
  
              Parameters[2] = Missing.Value;
  
              Object_WorkBook.GetType().InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, Object_WorkBook, Parameters);
  
  
  
              //Excel schließen
  
              Object_Excel_Application.GetType().InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, Object_Excel_Application, null);
  
  
  
              //Version in gekürtzter Form zurückgeben
  
              return version_long_to_version_short(version); //Die Hauptversionsnummer zurückgeben
  
          }//-try
  
          catch (Exception e) //bei Fehler
  
          {
  
              MessageBox.Show("Error: " + e.Message, "Error"); //Fehler anzeigen
  
              return String.Empty; //Leeren String zurückgeben
  
          }//-catch
  
          finally //Schlussendlich
  
          {
  
              //Die objecte wieder freigeben
  
              Object_freigeben(Object_WorkBook);
  
              Object_freigeben(Object_WorkBooks);
  
              Object_freigeben(Object_Excel_Application);
  
          }//-finally
  
      }//-CalculationVersion
  </code></pre>
  
  <p>Now I am trying to fix the problem that Excel 97 files seem not to store this, so I have this C++ that is used to determine if the bof of the file tells me that it is an Excel 97 (outputs 8) or any other version (outputs 0). The plan is to execute this and if it gives me a <code>0</code> I will get the <code>CalculationVersion</code>, otherwise I know that its Excel 97. <code>-1</code>, <code>-2</code>,<code>-3</code> are errors. The next step if this works is to "translate" my C++ to C# if possible and integrate it into my program.</p>
  
  <p>Sorry for German comments but my English is not so good.</p>