dotnet/wpf · error · ObjectDisposedException
EncryptedPackageEnvelope object was disposed.
Error message
EncryptedPackageEnvelope object was disposed.
What it means
CheckDisposed guards every public accessor of EncryptedPackageEnvelope (Flush, RightsManagementInformation, PackageProperties, FileOpenAccess, GetPackage, StorageInfo). After Dispose, any of these members throws ObjectDisposedException because the underlying compound file has been released.
Solutions
- Keep all envelope usage inside the scope where it is not disposed; move using blocks outward to cover all accesses
- Reopen the envelope (EncryptedPackageEnvelope.Open) if you need access after disposal
- Check _disposed-equivalent via a wrapper: track disposal in your own code and avoid calling members afterwards
Example fix
// before
EncryptedPackageEnvelope env;
using (env = EncryptedPackageEnvelope.Open(path)) { }
var props = env.PackageProperties; // ObjectDisposedException
// after
using (var env = EncryptedPackageEnvelope.Open(path))
{
var props = env.PackageProperties; // access inside scope
} Defensive patterns
Strategy: type-guard
Validate before calling
// track disposal in a wrapper
bool _disposed;
void UseEnvelope(EncryptedPackageEnvelope env) { if (_disposed) throw new ObjectDisposedException(nameof(env)); } Type guard
bool IsUsable(EncryptedPackageEnvelope env, Func<object> probe) { try { probe(); return true; } catch (ObjectDisposedException) { return false; } } Try / catch
try { var props = env.PackageProperties; }
catch (ObjectDisposedException) { env = EncryptedPackageEnvelope.Open(path); /* reopen */ } Prevention
- Scope all envelope usage inside the using block
- Never cache the envelope beyond its disposal scope
- Reopen the envelope rather than reusing a disposed instance
When it happens
Trigger: Using an EncryptedPackageEnvelope after calling Dispose (explicitly or via using-block exit), e.g. reading PackageProperties after the using scope ends, or caching the envelope and using it after disposal.
Common situations: Returning the envelope from a method whose using block closed it; storing the envelope in a field while disposing it in another code path; double-dispose followed by further use.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.StorageBasedPackagePropertiesDiposed
- SR.StreamObjectDisposed
- SR.ByteRangeDownloaderDisposed
- SR.StorageRootDisposed
- SR.StreamObjectDisposed
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7e2e5afb1caf717f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/EncryptedPackage.cs:1064
{
//
// By setting _disposed = true, we ensure that all future accesses to
// this object will fail (because all public methods and property accessors
// call CheckDisposed). Note that we do -not- wrap the entire body of
// Dispose(bool) (this method) in an "if (!_disposed)". This is safe
// because we set each reference to null immediately after attempting
// to release it, so we never attempt to release any reference more
// than once.
//
_disposed = true;
}
}
private void
CheckDisposed()
{
if (_disposed)
throw new ObjectDisposedException(null, SR.EncryptedPackageEnvelopeDisposed);
}
/// <summary>
/// Create a stream in the "encrypted" data space to hold the package
/// contents, and copy the package into that stream.
/// </summary>
/// <param name="packageStream">
/// A stream containing an unencrypted package which is to be stored in
/// the compound file.
/// </param>
private void
EmbedPackage(Stream packageStream)
{
StreamInfo siPackage = new StreamInfo(_root, PackageStreamName);
Debug.Assert(!siPackage.InternalExists());
//View on GitHub (pinned to 81131a70a4)