Question: I am using the following code under ASP.NET 4.0 framework to obtain the version of MSI file from a web app:

```
string strVersion = "";

try
{
    Type InstallerType;
    WindowsInstaller.Installer installer;

    InstallerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
    installer = (WindowsInstaller.Installer)Activator.CreateInstance(InstallerType);

    WindowsInstaller.Database db = installer.OpenDatabase(strMSIFilePath, 0);

    WindowsInstaller.View dv = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'");

    WindowsInstaller.Record record = null;

    dv.Execute(record);

    record = dv.Fetch();

    strVersion = record.get_StringData(1).ToString();

    dv.Close();
    //db.Commit();
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(dv);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
}
catch
{
    //Failed
    strVersion = "";
}

```

It works fine except that when the code finishes running it holds an internal MSI file handle so when I try to move or rename the MSI file I get the error that the file is still in use. This continues until I actually navigate away from the ASPX page that calls the method above.

My question is, I obviously didn't close some handle or object in the code above. But what could that be?

PS. I'm testing it in a development IDE from VS2010.

**EDIT:** Edited the code like it should be after Adriano's suggestion. Thanks!

Answer: 
The COM object has not been released (it should be auto-released when it goes out of scope but in .NET this doesn't work really well). Because it does not implement the `IDisposable` interface you can't call its `Dispose()` method and you can't use it inside an `using` statement. You have to explicitly call [Marshal.FinalReleaseComObject](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.finalreleasecomobject%28v=vs.100%29.aspx). For example:

```
try
{
    // Your stuffs
}
finally
{
    dv.Close();
    Marshal.FinalReleaseComObject(dv);
    Marshal.FinalReleaseComObject(db);
}

```

Moreover note that you do not really need a call to the `Commit()` method because you didn't make any change but just a query.
try to `Dispose` the Objects.

```
dv.Dispose();
db.Dispose();

```