Skip to content

Fix file lock error when saving cropped image on network drives#157

Open
Slashxdd wants to merge 1 commit intoModuleArt:feature/new-webp-decoderfrom
Slashxdd:fix/crop-save-file-lock-v2
Open

Fix file lock error when saving cropped image on network drives#157
Slashxdd wants to merge 1 commit intoModuleArt:feature/new-webp-decoderfrom
Slashxdd:fix/crop-save-file-lock-v2

Conversation

@Slashxdd
Copy link
Copy Markdown

Fixes #153

Problem

When opening an image (especially from a network drive), cropping it, and saving with Ctrl+S, the application throws an error saying the file is busy/locked.

Root cause β€” two independent bugs:

1. BitmapWrapper.cs β€” new Bitmap(path) holds the file locked

In .NET GDI+, constructing a Bitmap directly from a file path keeps an open file handle for the entire lifetime of the object. On local drives the OS typically allows overwriting a file you hold open, but on network (SMB) drives file locking is strict and the subsequent FileStream write fails with "file is busy".

Fix: read the file into a MemoryStream first (File.ReadAllBytes), create a temporary Bitmap from the stream, then copy it with new Bitmap(tmp) β€” which produces a fully independent in-memory copy. The file handle is released immediately.

2. MainForm.cs β†’ cropBtn_Click β€” old Bitmap never disposed

// Before (bug):
originalImage = originalImage.Clone(...);
// Old Bitmap (with the file lock) is orphaned β€” disposed only when GC decides to run

After cropping, the old Bitmap (which holds the file lock) was simply overwritten without being explicitly disposed. The GC would eventually collect it, but until then the file remained locked β€” so Ctrl+S would fail on network drives where the timing is most critical.

// After (fix):
Bitmap oldImage = originalImage;
originalImage = oldImage.Clone(...);
pictureBox.Image = originalImage;  // update UI first
oldImage.Dispose();                // then explicitly release the lock

3. IcoWrapper.cs β€” Icon(path, ...) not in a using block

Same class of bug: the Icon object was created without using, so its file handle was only released non-deterministically by the GC.

Files changed

File Change
typewrappers/BitmapWrapper.cs Load via MemoryStream to avoid holding a file lock
typewrappers/IcoWrapper.cs Wrap Icon in a using block so the handle is released immediately
forms/MainForm.cs Dispose old Bitmap explicitly in cropBtn_Click before reassigning

Resolves ModuleArt#153: the viewer held the source file locked during save,
causing "file is busy" errors especially on network (SMB) drives.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant