Burn the files on CD with the full directory tree structure.

Dani_S 3,746 Reputation points
2024-08-22T11:26:40.8333333+00:00

The application built on C# Winforms, Framework 4.6.2 and there is the need to burn all the files and folders from the root folder, including itself to CD.

The entry parameter is the source root folder path. The folder contains inside all of the needed to copy to the CD. Think to use the built-in Windows 10/11 burner for this purpose. I know, Windows prepares and precopies the source files for the burning inside the the temporary folder, on the path C:\Users*UserName*\AppData\Local\Microsoft\Windows\Burn\Burn Now, how to tell to built-in burner to take this tree with files and folders, and to copy it to the CD?

Do I need to build some map structure file before? Hoow it works?

Any answers will be appreciated.

Thank you in advance,

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,884 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,858 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Castorix31 84,546 Reputation points
    2024-08-22T15:21:50.6833333+00:00

    There is an old MS sample but it crashed on my PC : https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winbase/imapi/IBurnBut this test worked on my Windows 10 OS (22H2) :

    {
        Guid CLSID_CDBurn = new Guid("fbeb8a05-beee-4442-804e-409d6c4515e9");
        var pCDBurn = (ICDBurn)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CDBurn));
        
        StringBuilder sbDriveLetter = new StringBuilder(255);
        HRESULT hr = pCDBurn.GetRecorderDriveLetter(sbDriveLetter, (uint)sbDriveLetter.Capacity);
        string sDriveLetter = sbDriveLetter.ToString();
        IntPtr pPath = IntPtr.Zero;
        hr = SHGetKnownFolderPath(FOLDERID_CDBurning, 0, IntPtr.Zero, out pPath);
        // C:\Users\Christian\AppData\Local\Microsoft\Windows\Burn\Burn
        string sPath = Marshal.PtrToStringUni(pPath);
    
        string sSource = @"E:\Images\Fire";
        string sDest = sPath;
        var fos = new SHFILEOPSTRUCT
        {
            wFunc = FO.FO_COPY,
            pFrom = sSource + '\0',
            pTo = sDest + '\0',
            fFlags = FILEOP_FLAGS.FOF_ALLOWUNDO
        };
        int nReturn = SHFileOperation(ref fos);
    
        pCDBurn.Burn(this.Handle);
    }
    
    

    with :

            [ComImport, Guid("3d73a659-e5d0-4d42-afc0-5121ba425c8d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
            public interface ICDBurn
            {
                HRESULT GetRecorderDriveLetter(StringBuilder pszDrive, uint cch);
                HRESULT Burn(IntPtr hwnd);
                HRESULT HasRecordableDrive(out bool pfHasRecorder);
            }
    
            public enum HRESULT : int
            {
                S_OK = 0,
                S_FALSE = 1,
                E_NOINTERFACE = unchecked((int)0x80004002),
                E_NOTIMPL = unchecked((int)0x80004001),
                E_FAIL = unchecked((int)0x80004005),
                E_UNEXPECTED = unchecked((int)0x8000FFFF),
                E_OUTOFMEMORY = unchecked((int)0x8007000E)
            }
    
            [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern HRESULT SHGetKnownFolderPath([In, MarshalAs(UnmanagedType.LPStruct)] Guid rfid, int dwFlags, IntPtr hToken, out IntPtr ppszPath);
    
            public static readonly Guid FOLDERID_Desktop = new Guid(0xB4BFCC3A, 0xDB2C, 0x424C, 0xB0, 0x29, 0x7F, 0xE9, 0x9A, 0x87, 0xC6, 0x41);
            public static readonly Guid FOLDERID_CDBurning = new Guid(0x9E52AB10, 0xF80D, 0x49DF, 0xAC, 0xB8, 0x43, 0x30, 0xF5, 0x68, 0x78, 0x55);
    
            public enum FO : int
            {
                FO_MOVE = 0x0001,
                FO_COPY = 0x0002,
                FO_DELETE = 0x0003,
                FO_RENAME = 0x0004
            }
    
            [Flags]
            public enum FILEOP_FLAGS : uint
            {
                FOF_MULTIDESTFILES = 0x0001,
                FOF_CONFIRMMOUSE = 0x0002,
                FOF_SILENT = 0x0004,  // don't create progress/report
                FOF_RENAMEONCOLLISION = 0x0008,
                FOF_NOCONFIRMATION = 0x0010,  // Don't prompt the user.
                FOF_WANTMAPPINGHANDLE = 0x0020,  // Fill in SHFILEOPSTRUCT.hNameMappings
                                                 // Must be freed using SHFreeNameMappings
                FOF_ALLOWUNDO = 0x0040,
                FOF_FILESONLY = 0x0080,  // on *.*, do only files
                FOF_SIMPLEPROGRESS = 0x0100,  // means don't show names of files
                FOF_NOCONFIRMMKDIR = 0x0200,  // don't confirm making any needed dirs
                FOF_NOERRORUI = 0x0400,  // don't put up error UI
                FOF_NOCOPYSECURITYATTRIBS = 0x0800,  // dont copy NT file Security Attributes
                FOF_NORECURSION = 0x1000,  // don't recurse into directories.
                FOF_NO_CONNECTED_ELEMENTS = 0x2000,  // don't operate on connected file elements.
                FOF_WANTNUKEWARNING = 0x4000,  // during delete operation, warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION)
                FOF_NORECURSEREPARSE = 0x8000,  // treat reparse points as objects, not containers
    
                FOFX_NOSKIPJUNCTIONS = 0x00010000,  // Don't avoid binding to junctions (like Task folder, Recycle-Bin)
                FOFX_PREFERHARDLINK = 0x00020000,  // Create hard link if possible
                FOFX_SHOWELEVATIONPROMPT = 0x00040000,  // Show elevation prompts when error UI is disabled (use with FOF_NOERRORUI)
                FOFX_EARLYFAILURE = 0x00100000,  // Fail operation as soon as a single error occurs rather than trying to process other items (applies only when using FOF_NOERRORUI)
                FOFX_PRESERVEFILEEXTENSIONS = 0x00200000,  // Rename collisions preserve file extns (use with FOF_RENAMEONCOLLISION)
                FOFX_KEEPNEWERFILE = 0x00400000,  // Keep newer file on naming conflicts
                FOFX_NOCOPYHOOKS = 0x00800000,  // Don't use copy hooks
                FOFX_NOMINIMIZEBOX = 0x01000000,  // Don't allow minimizing the progress dialog
                FOFX_MOVEACLSACROSSVOLUMES = 0x02000000,  // Copy security information when performing a cross-volume move operation
                FOFX_DONTDISPLAYSOURCEPATH = 0x04000000,  // Don't display the path of source file in progress dialog
                FOFX_DONTDISPLAYDESTPATH = 0x08000000,  // Don't display the path of destination file in progress dialog
            }
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
            public struct SHFILEOPSTRUCT
            {
                public IntPtr hwnd;
                [MarshalAs(UnmanagedType.U4)]
                public FO wFunc;
                public string pFrom;
                public string pTo;
                public FILEOP_FLAGS fFlags;
                [MarshalAs(UnmanagedType.Bool)]
                public bool fAnyOperationsAborted;
                public IntPtr hNameMappings;
                public string lpszProgressTitle;
            }
    
            [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
    
    
    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.