ahm*_*md0 3 .net c# asp.net windows-installer com-interop
我在ASP.NET 4.0框架下使用以下代码从Web应用程序获取MSI文件的版本:
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 = "";
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,但是当代码完成运行时它保存一个内部MSI文件句柄,所以当我尝试移动或重命名MSI文件时,我得到文件仍在使用的错误.这一直持续到我实际离开调用上述方法的ASPX页面.
我的问题是,我显然没有在上面的代码中关闭一些句柄或对象.但这可能是什么?
PS.我正在VS2010的开发IDE中测试它.
编辑:编辑代码应该是在阿德里亚诺的建议之后.谢谢!
COM对象尚未发布(它应该在超出范围时自动释放,但在.NET中这不能很好地工作).因为它没有实现IDisposable接口,所以无法调用其Dispose()方法,也无法在using语句中使用它.您必须显式调用Marshal.FinalReleaseComObject.例如:
try
{
// Your stuffs
}
finally
{
dv.Close();
Marshal.FinalReleaseComObject(dv);
Marshal.FinalReleaseComObject(db);
}
Run Code Online (Sandbox Code Playgroud)
此外请注意,您并不需要调用该Commit()方法,因为您没有进行任何更改,只是查询.
| 归档时间: |
|
| 查看次数: |
1970 次 |
| 最近记录: |