ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c#-将流作为文件添加到ISO

2019-11-20 07:09:33  阅读:489  来源: 互联网

标签:stream filesystems imapi c


我在Windows中使用IMAPI2FS映像母带API,并且试图在生成ISO之前弄清楚如何将流作为文件添加到文件系统映像中.

var fsi = new MsftFileSystemImage();
fsi.ChooseImageDefaultsForMediaType(IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK);
fsi.FileSystemsToCreate = 
    FsiFileSystems.FsiFileSystemISO9660 | FsiFileSystems.FsiFileSystemJoliet;

using (var stream = new MemoryStream())
{
    stream.Write(buffer, 0, bufferSize);

    // Here is where I need to either instantiate an FsiStream and copy
    // stream to it, but I can't figure out how to do this.

    fsi.Root.AddFile(relativePathFromImageRoot, iStreamObject);
}

解决方法:

您正在尝试使用IMAPI2FS类型库,并且遇到该库的常见问题.它的编写能力很差,并且很难直接从.NET程序使用.大多数针对api的程序都是用C编写的,并且使用imap2fs.h SDK头文件.

您在此处遇到的一个具体问题是类型库导入程序将AddFile()的第二个参数转换为FsiStream(一种共类类型).这是您无法创建的类型,它具有[noncreatable]类型库属性.类型库转换器被误入歧途,该方法实际上带有IStream参数.您应该做的是创建自己的IStream实现,并将其实例作为第二个参数传递.

可以在C#版本4动态关键字的帮助下解决此问题,以便编译器不会抱怨FsiStream.这是实现IStream的示例实现类:

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.IO;

[ComVisible(true)]
class FsiStreamImpl : IStream {
    private Stream source;
    private FsiStreamImpl() { }
    public static dynamic Create(Stream from) {
        var stream = new FsiStreamImpl();
        stream.source = from;
        return stream;
    }

    public void Read(byte[] pv, int cb, IntPtr pcbRead) {
        int read = source.Read(pv, 0, cb);
        Marshal.WriteInt32(pcbRead, read);
    }

    public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) {
        long pos = source.Seek(dlibMove, (SeekOrigin)dwOrigin);
        Marshal.WriteInt64(plibNewPosition, pos);
    }

    public void Stat(out STATSTG pstatstg, int grfStatFlag) {
        var stat = new STATSTG();
        stat.type = 2;
        stat.cbSize = source.Length;
        stat.grfMode = 2;
        pstatstg = stat;
    }

    // Methods that we don't have to implement:
    public void Write(byte[] pv, int cb, IntPtr pcbWritten) {
        throw new NotImplementedException();
    }
    public void Clone(out IStream ppstm) {
        throw new NotImplementedException();
    }
    public void Commit(int grfCommitFlags) {
        throw new NotImplementedException();
    }
    public void SetSize(long libNewSize) {
        throw new NotImplementedException();
    }
    public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) {
        throw new NotImplementedException();
    }
    public void LockRegion(long libOffset, long cb, int dwLockType) {
        throw new NotImplementedException();
    }
    public void Revert() {
        throw new NotImplementedException();
    }
    public void UnlockRegion(long libOffset, long cb, int dwLockType) {
        throw new NotImplementedException();
    }
}

现在您可以像这样编写代码:

using (var stream = new MemoryStream(buffer))
{
    stream.Write(buffer, 0, bufferSize);
    stream.Position = 0;
    fsi.Root.AddFile(relativePathFromImageRoot, FsiStreamImpl.Create(stream)));
}

或像这样的代码,我测试了什么:

using (var file = new FileStream(@"c:\temp\test.txt", FileMode.Open, FileAccess.Read)) {
    fsi.Root.AddFile("test.txt", FsiStreamImpl.Create(file));
}

您可能会遇到更多问题,我只测试了您发布的代码段.我应该指出这个Codeproject.com project,它也是由与IMAPI2作战的程序员编写的.他采用了更为广泛的方法,这是一种相当危险的方法,并使用手工制作的C#声明重写了整个类型库.他花了很多时间,支持问题只集中在学习如何使用IMAPI2上,因此您可以依靠它.

标签:stream,filesystems,imapi,c
来源: https://codeday.me/bug/20191120/2042196.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有