So it works ihave changed the RunUpdates method in Zipfile.cs:
void RunUpdates()
{
long sizeEntries = 0;
long endOfStream = 0;
bool allOk = true;
bool directUpdate = false;
bool zipContinue = false;
string msg="";
long destinationPosition = 0; // NOT SFX friendly
ZipFile workFile;
if ( IsNewArchive ) {
workFile = this;
workFile.baseStream_.Position = 0;
directUpdate = true;
}
else if ( archiveStorage_.UpdateMode == FileUpdateMode.Direct ) {
workFile = this;
workFile.baseStream_.Position = 0;
directUpdate = true;
// Sort the updates by offset within copies/modifies, then adds.
// This ensures that data required by copies will not be overwritten.
updates_.Sort(new UpdateComparer());
}
else {
workFile = ZipFile.Create(archiveStorage_.GetTemporaryOutput());
workFile.UseZip64 = UseZip64;
if (key != null) {
workFile.key = (byte[)key.Clone();
}
}
try
{
foreach (ZipUpdate update in updates_)
{
if (update != null)
{
switch (update.Command)
{
case UpdateCommand.Copy:
if (directUpdate)
{
CopyEntryDirect(workFile, update, ref destinationPosition);
}
else
{
CopyEntry(workFile, update);
}
break;
case UpdateCommand.Modify:
// TODO: Direct modifying of an entry will take some legwork.
ModifyEntry(workFile, update);
break;
case UpdateCommand.Add:
if (!IsNewArchive && directUpdate)
{
workFile.baseStream_.Position = destinationPosition;
}
AddEntry(workFile, update);
if (directUpdate)
{
destinationPosition = workFile.baseStream_.Position;
}
break;
}
}
}
if (!IsNewArchive && directUpdate)
{
workFile.baseStream_.Position = destinationPosition;
}
long centralDirOffset = workFile.baseStream_.Position;
foreach (ZipUpdate update in updates_)
{
if (update != null)
{
sizeEntries += workFile.WriteCentralDirectoryHeader(update.OutEntry);
}
}
byte[ theComment = (newComment_ != null) ? newComment_.RawComment : ZipConstants.ConvertToArray(comment_);
using (ZipHelperStream zhs = new ZipHelperStream(workFile.baseStream_))
{
zhs.WriteEndOfCentralDirectory(updateCount_, sizeEntries, centralDirOffset, theComment);
}
endOfStream = workFile.baseStream_.Position;
// And now patch entries...
foreach (ZipUpdate update in updates_)
{
if (update != null)
{
// If the size of the entry is zero leave the crc as 0 as well.
// The calculated crc will be all bits on...
if ((update.CrcPatchOffset > 0) && (update.OutEntry.CompressedSize > 0))
{
workFile.baseStream_.Position = update.CrcPatchOffset;
workFile.WriteLEInt((int)update.OutEntry.Crc);
}
if (update.SizePatchOffset > 0)
{
workFile.baseStream_.Position = update.SizePatchOffset;
if (update.OutEntry.LocalHeaderRequiresZip64)
{
workFile.WriteLeLong(update.OutEntry.Size);
workFile.WriteLeLong(update.OutEntry.CompressedSize);
}
else
{
workFile.WriteLEInt((int)update.OutEntry.CompressedSize);
workFile.WriteLEInt((int)update.OutEntry.Size);
}
}
}
}
}
catch (IOException ex)
{
if (ex.Message.EndsWith(" because it is being used by another process."))
{
msg = ex.Message;
allOk = false;
zipContinue = true;
}
else
{
allOk = false;
zipContinue = false;
}
}
catch (Exception)
{
allOk = false;
zipContinue = false;
}
finally {
if ( directUpdate ) {
if ( allOk ) {
workFile.baseStream_.Flush();
workFile.baseStream_.SetLength(endOfStream);
}
}
else {
workFile.Close();
}
}
if ( allOk ) {
if ( directUpdate ) {
isNewArchive_ = false;
workFile.baseStream_.Flush();
ReadEntries();
}
else {
baseStream_.Close();
Reopen(archiveStorage_.ConvertTemporaryToFinal());
}
}
else {
if (!zipContinue)
{
workFile.Close();
if (!directUpdate && (workFile.Name != null))
{
File.Delete(workFile.Name);
}
}
else
{
throw(new Exception(msg));
}
}
}