What is the best way to make .ISO files based on a file folder structure from C#? Is there an open source library other than DiscUtils? Running into issues with DiscUtils and I'd like try another path. What are my options? I'd prefer open source but might also be willing to pay for a solution.
Asked
Active
Viewed 8,295 times
3 Answers
5
Here are some more to try
- C# [ISO] image creator (no support for audio CDs)
- IsoCreator

SliverNinja - MSFT
- 31,051
- 11
- 110
- 173

Micah Armantrout
- 6,781
- 4
- 40
- 66
5
Windows actually comes with a native API for creating ISOs and much more: the Image Mastering API. Once you grab the IMAPI2 Interop assembly from the Windows SDK or (probably easier) from this CodeProject article about IMAPI2, creating an ISO is only a few lines of code.
Unfortunately, you also need a few paragraphs to properly clean up the COM nonsense involved, but the end result is still pretty manageable:
MsftFileSystemImage iso = new MsftFileSystemImage();
iso.ChooseImageDefaultsForMediaType(IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK);
iso.FileSystemsToCreate = FsiFileSystems.FsiFileSystemISO9660 | FsiFileSystems.FsiFileSystemJoliet;
iso.Root.AddTree(@"c:\path\goes\here\", false);
dynamic resultImage = iso.CreateResultImage();
dynamic imageStream = resultImage.ImageStream;
IStream newStream = null;
if (imageStream != null)
{
STATSTG stat = null;
imageStream.Stat(stat, 0x1);
int res = SHCreateStreamOnFile(@"c:\path\to\your.iso", 0x1001, newStream);
if (res == 0 && newStream != null)
{
IntPtr inBytes = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(long)));
IntPtr outBytes = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(long)));
try
{
imageStream.CopyTo(newStream, stat.cbSize, inBytes, outBytes);
}
finally
{
Marshal.FinalReleaseComObject(imageStream);
newStream.Commit(0);
Marshal.FinalReleaseComObject(newStream);
Marshal.FreeHGlobal(inBytes);
Marshal.FreeHGlobal(outBytes);
Marshal.FinalReleaseComObject(resultImage);
Marshal.FinalReleaseComObject(iso);
}
}
else
{
Marshal.FinalReleaseComObject(imageStream);
Marshal.FinalReleaseComObject(resultImage);
Marshal.FinalReleaseComObject(iso);
//TODO: Throw exception or do whatever to signal failure here
}
}
else
{
Marshal.FinalReleaseComObject(resultImage);
Marshal.FinalReleaseComObject(iso);
//TODO: Throw exception or do whatever to signal failure here
}
Details for the only bit of Win32/COM API glue used can be found on pinvoke.net: SHCreateStreamOnFile. IStream and STATSTG are in System.Runtime.InteropServices.ComTypes..

Wai Ha Lee
- 8,598
- 83
- 57
- 92

mdb
- 52,000
- 11
- 64
- 62
-
1The code here doesn't seem to work as written; there are multiple issues with types and function parameters. The example should also show the appropriate `using` statements and P/Invoke declarations required. – Herohtar Nov 19 '19 at 05:40
-
Also, calling `Marshal.FinalReleaseComObject` is not required (and is in fact potentially bad). The runtime takes care of the references automatically. – Herohtar Nov 23 '19 at 05:55