Как явно создать структуру каталогов в ISO-файле, созданном с помощью IMAPI? - PullRequest
0 голосов
/ 02 октября 2018

Я скопировал программу, которая записывает файл ISO, используя IMAPI.Кажется, чтобы сократить имена каталогов.Например, если я вызываю эту функцию:

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

То, что я получаю в ISO:

SUBDIR\file 1
SUBDIR\file 2
...

Часть "DIR" отбрасывается.

ЧтоЯ хочу это:

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

Я видел Создайте папку на диске и запишите ее, используя 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 Ответ

0 голосов
/ 02 октября 2018

Я думаю, что понял.Решением является создание каталога, присоединение каталога к файлу 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, с которым мне приходилось иметь дело.

...