/// <summary> /// Disposes the managed and unmanaged objects in this object. /// </summary> /// <param name="disposing">true to dispose the managed objects.</param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (0 != this.handle) { if (Thread.CurrentThread.ManagedThreadId == this.owningThread) { int error = MsiInterop.MsiCloseHandle(this.handle); if (0 != error) { throw new Win32Exception(error); } this.handle = 0; } else { // Don't try to close the handle on a different thread than it was opened. // This will occasionally cause MSI to AV. string message = String.Format("Leaked msi handle {0} created on thread {1} by type {2}. This handle cannot be closed on thread {3}", this.handle, this.owningThread, this.GetType(), Thread.CurrentThread.ManagedThreadId); #if DEBUG throw new InvalidOperationException(String.Format("{0}. Created {1}", message, this.creationStack)); #else Debug.WriteLine(message); #endif } } this.disposed = true; } }