代码之家  ›  专栏  ›  技术社区  ›  Pierre

如何在用IMAPI创建的ISO文件中显式地创建目录结构?

  •  2
  • Pierre  · 技术社区  · 6 年前

    我复制了一个使用IMAPI编写ISO文件的程序。它似乎截断了目录名。例如,如果我调用此函数:

    image.Root.AddTree("C:\\DIR\\SUBDIR", true);
    

    我在ISO中得到的是:

    SUBDIR\file 1
    SUBDIR\file 2
    ...
    

    “DIR”部分被删除。

    我想要的是:

    DIR\SUBDIR\file 1
    DIR\SUBDIR\file 2
    ...
    

    我见过 Create a folder in disk and Burn Into it using IMAPI 2 ,其中一个回复建议使用

    rootItem.AddDirectory(directoryName);
    rootItem.get_Item(directoryName, newDirItem);   
    

    但是 get_Item 导致编译错误“无法显式调用运算符或访问器”

    关于如何在ISO文件中显式创建目录(并写入目录)有什么建议吗?

    这是密码。将IMAPI2和IMAPI2FS添加到引用中。

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using IMAPI2FS;     // COM reference: Microsoft IMAPI2 File System Image Creator
    using IStream = System.Runtime.InteropServices.ComTypes.IStream;
    using STATSTG = System.Runtime.InteropServices.ComTypes.STATSTG;
    
    namespace CreateISO
    {
    
        class IsoImage
        {
            [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
            static extern void SHCreateStreamOnFile(string pszFile, uint grfMode, out IStream ppstm);
    
            public void CreateISO(string path)
            {
                var image = (IFileSystemImage)new MsftFileSystemImage();    // same as Activator.CreateInstance(Type.GetTypeFromProgID("IMAPI2FS.MsftFileSystemImage"))
                image.ChooseImageDefaultsForMediaType(IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK);
                image.FileSystemsToCreate = FsiFileSystems.FsiFileSystemJoliet | FsiFileSystems.FsiFileSystemISO9660;
                image.VolumeName = Path.GetDirectoryName(path);
                image.Root.AddTree(path, true);
    
                var inStream = (IStream)image.CreateResultImage().ImageStream;
                STATSTG stat;
                inStream.Stat(out stat, 0x01);
                IStream outStream;
                SHCreateStreamOnFile("C:\\temp\\demo.iso", 0x00001001, out outStream);
    
                unsafe
                {
                    long inBytes;
                    long outBytes;
                    long* pin = &inBytes;
                    long* pout = &outBytes;
                    inStream.CopyTo(outStream, stat.cbSize, (IntPtr)pin, (IntPtr)pout);
                    outStream.Commit(0);
                }
            }
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Pierre    6 年前

    我想我明白了。解决方案是创建一个目录,将该目录附加到ISO文件,然后将子目录添加到新对象:

            IFsiDirectoryItem newItem = image.CreateDirectoryItem("DIR");
            image.Root.Add(newItem);
            newItem.AddTree("C:\\DIR\\SUBDIR", true);
    

    瞧,ISO看起来像:

    DIR\SUBDIR\file 1
    DIR\SUBDIR\file 2
    ...
    

    要创建多级目录,请执行以下操作:

            IFsiDirectoryItem newDir = image.CreateDirectoryItem("DIR");
            IFsiDirectoryItem newDir2 = image.CreateDirectoryItem("SUBDIR1");
            image.Root.Add(newDir);   // must be added first
            newDir.Add(newDir2);
            newDir2.AddTree("C:\\DIR\\SUBDIR1\\SUBDIR2", true);
    

    我必须说,这不是我必须处理的最直观的API。

    推荐文章