Вы пытаетесь использовать библиотеку типов 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, чтобы вы, вероятно, были в этом уверены.