public override void Write(byte[] buffer, int offset, int count) { WriteStream.Write(buffer, offset, count); }
private void _SaveSfxStub(string exeToGenerate, SelfExtractorFlavor flavor, string defaultExtractLocation, string postExtractCmdLine, string nameOfIconFile) { bool removeIconFile = false; string StubExe = null; string TempDir = null; try { if (File.Exists(exeToGenerate)) { if (Verbose) { StatusMessageTextWriter.WriteLine("The existing file ({0}) will be overwritten.", exeToGenerate); } } if (!exeToGenerate.EndsWith(".exe")) { if (Verbose) { StatusMessageTextWriter.WriteLine("Warning: The generated self-extracting file will not have an .exe extension."); } } StubExe = GenerateTempPathname("exe", null); // get the Ionic.Zip assembly Assembly a1 = typeof(ZipFile).Assembly; Microsoft.CSharp.CSharpCodeProvider csharp = new Microsoft.CSharp.CSharpCodeProvider(); // Perfect opportunity for a linq query, but I cannot use it. // The DotNetZip library can compile into 2.0, but needs to run on .NET 2.0. // Using LINQ would break that. Here's what it would look like: // // var settings = (from x in SettingsList // where x.Flavor == flavor // select x).First(); ExtractorSettings settings = null; foreach (var x in SettingsList) { if (x.Flavor == flavor) { settings = x; break; } } if (settings == null) { throw new BadStateException(String.Format("While saving a Self-Extracting Zip, Cannot find that flavor ({0})?", flavor)); } // This is the list of referenced assemblies. Ionic.Zip is needed here. // Also if it is the winforms (gui) extractor, we need other referenced assemblies, // like System.Windows.Forms.dll, etc. System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters(); cp.ReferencedAssemblies.Add(a1.Location); if (settings.ReferencedAssemblies != null) { foreach (string ra in settings.ReferencedAssemblies) { cp.ReferencedAssemblies.Add(ra); } } cp.GenerateInMemory = false; cp.GenerateExecutable = true; cp.IncludeDebugInformation = false; cp.CompilerOptions = ""; Assembly a2 = Assembly.GetExecutingAssembly(); if (nameOfIconFile == null) { removeIconFile = true; nameOfIconFile = GenerateTempPathname("ico", null); ExtractResourceToFile(a2, "Ionic.Zip.Resources.zippedFile.ico", nameOfIconFile); cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", nameOfIconFile); } else if (nameOfIconFile != "") { cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", nameOfIconFile); } //cp.IncludeDebugInformation = true; cp.OutputAssembly = StubExe; if (flavor == SelfExtractorFlavor.WinFormsApplication) { cp.CompilerOptions += " /target:winexe"; } if (cp.CompilerOptions == "") { cp.CompilerOptions = null; } TempDir = GenerateTempPathname("tmp", null); if ((settings.CopyThroughResources != null) && (settings.CopyThroughResources.Count != 0)) { System.IO.Directory.CreateDirectory(TempDir); foreach (string re in settings.CopyThroughResources) { string filename = Path.Combine(TempDir, re); ExtractResourceToFile(a2, re, filename); // add the file into the target assembly as an embedded resource cp.EmbeddedResources.Add(filename); } } // add the Ionic.Utils.Zip DLL as an embedded resource cp.EmbeddedResources.Add(a1.Location); //Console.WriteLine("Resources in this assembly:"); //foreach (string rsrc in a2.GetManifestResourceNames()) //{ // Console.WriteLine(rsrc); //} //Console.WriteLine(); //Console.WriteLine("reading source code resources:"); // concatenate all the source code resources into a single module var sb = new System.Text.StringBuilder(); // assembly attributes sb.Append("[assembly: System.Reflection.AssemblyTitle(\"DotNetZip SFX Archive\")]\n"); sb.Append("[assembly: System.Reflection.AssemblyProduct(\"ZipLibrary\")]\n"); sb.Append("[assembly: System.Reflection.AssemblyCopyright(\"Copyright © Dino Chiesa 2008, 2009\")]\n"); sb.Append(String.Format("[assembly: System.Reflection.AssemblyVersion(\"{0}\")]\n\n", ZipFile.LibraryVersion.ToString())); // Set the default extract location if it is available, and if supported. bool haveLocation = (defaultExtractLocation != null); if (haveLocation) { defaultExtractLocation = defaultExtractLocation.Replace("\"", "").Replace("\\", "\\\\"); } foreach (string rc in settings.ResourcesToCompile) { //Console.WriteLine(" trying to read stream: ({0})", rc); Stream s = a2.GetManifestResourceStream(rc); if (s == null) { throw new ZipException(String.Format("missing resource '{0}'", rc)); } using (StreamReader sr = new StreamReader(s)) { while (sr.Peek() >= 0) { string line = sr.ReadLine(); if (haveLocation) { line = line.Replace("@@EXTRACTLOCATION", defaultExtractLocation); } if (postExtractCmdLine != null) { line = line.Replace("@@POST_UNPACK_CMD_LINE", postExtractCmdLine.Replace("\\", "\\\\")); } sb.Append(line).Append("\n"); } } sb.Append("\n\n"); } string LiteralSource = sb.ToString(); #if DEBUGSFX // for debugging only string sourceModule = GenerateTempPathname("cs", null); using (StreamWriter sw = File.CreateText(sourceModule)) { sw.Write(LiteralSource); } Console.WriteLine("source: {0}", sourceModule); #endif System.CodeDom.Compiler.CompilerResults cr = csharp.CompileAssemblyFromSource(cp, LiteralSource); if (cr == null) { throw new SfxGenerationException("Cannot compile the extraction logic!"); } if (Verbose) { foreach (string output in cr.Output) { StatusMessageTextWriter.WriteLine(output); } } if (cr.Errors.Count != 0) { //Console.ReadLine(); string sourcefile = GenerateTempPathname("cs", null); using (TextWriter tw = new StreamWriter(sourcefile)) { tw.Write(LiteralSource); } throw new SfxGenerationException(String.Format("Errors compiling the extraction logic! {0}", sourcefile)); } OnSaveEvent(ZipProgressEventType.Saving_AfterCompileSelfExtractor); // Now, copy the resulting EXE image to the _writestream. // Because this stub exe is being saved first, the effect will be to // concatenate the exe and the zip data together. using (System.IO.Stream input = System.IO.File.OpenRead(StubExe)) { byte[] buffer = new byte[4000]; int n = 1; while (n != 0) { n = input.Read(buffer, 0, buffer.Length); if (n != 0) { WriteStream.Write(buffer, 0, n); } } } OnSaveEvent(ZipProgressEventType.Saving_AfterSaveTempArchive); } finally { try { if (Directory.Exists(TempDir)) { try { Directory.Delete(TempDir, true); } catch { } } if (File.Exists(StubExe)) { try { File.Delete(StubExe); } catch { } } if (removeIconFile && File.Exists(nameOfIconFile)) { try { File.Delete(nameOfIconFile); } catch { } } } catch { } } return; }
byte[] ReadBuffer = new byte[1024 * 128 * 1]; // кеш - 0.5 Мб void DownloadFileStreamly(Stream dataStream) { DownloadProgress CurrentDownloadProgress = new DownloadProgress(); Stream WriteStream = null; Exception TempEx = null; try { if (Current.DownloadPathSave != null) { string FilePath = Current.DownloadPathSave + "\\" + Current.Filename; if (System.IO.File.Exists(FilePath)) { System.IO.FileInfo xx = new System.IO.FileInfo(FilePath); if (xx.Length > Current.FileSize) { xx.Delete(); Current.BytesDownloaded = 0; } } else { Current.BytesDownloaded = 0; } WriteStream = new FileStream(FilePath, FileMode.OpenOrCreate); CurrentDownloadProgress.FilePath = FilePath; } else { WriteStream = Current.OutputData; } if (Current.FileSize == Current.BytesDownloaded && Current.BytesDownloaded != 0 && Current.FileDownloaded) { throw new Exception("Файл уже закачан " + Current.FullURL); } if (Current.FileSize > 0 && Current.BytesDownloaded == 0 && WriteStream.Length != Current.FileSize) { // если известен размер файла и файл только что добавили, то создаем пустышку в размер файла WriteStream.SetLength(Current.FileSize); } if (WriteStream.Length == Current.BytesDownloaded && WriteStream.Length != 0) { Current.BytesDownloaded = 0; } WriteStream.Position = Current.BytesDownloaded; DateTime BeginTime = DateTime.Now; TimeSpan TimeDifference; TimeSpan RemainTime; int BeginDownloadBytes = Current.BytesDownloaded; int ReadData = 1; int BufferOffset = 0; double LastTimeDifferenceSeconds = 0; while (DownloadFileThreadRunning) { if (!DownloadFileThreadPause) { // если не была задана пауза ReadData = dataStream.Read(ReadBuffer, BufferOffset, ReadBuffer.Length - BufferOffset); BufferOffset += ReadData; TimeDifference = DateTime.Now - BeginTime; if (((ReadBuffer.Length - BufferOffset) < 1024) || // осталось черезчур мало места в буффере (ReadData == 0) || // закачка закончилась (TimeDifference.TotalSeconds != LastTimeDifferenceSeconds)) // но не реже 1 раза в секунду { WriteStream.Write(ReadBuffer, 0, BufferOffset); Current.BytesDownloaded += BufferOffset; if (TimeDifference.TotalSeconds != LastTimeDifferenceSeconds) { CurrentDownloadProgress.DownloadSize = Math.Max(Current.BytesDownloaded, Current.FileSize); CurrentDownloadProgress.Bytes = Current.BytesDownloaded; CurrentDownloadProgress.Speed = ( (Current.BytesDownloaded - BeginDownloadBytes) * 1000.0f / (float)TimeDifference.TotalMilliseconds); RemainTime = new TimeSpan((long) ((TimeDifference.Ticks * (Current.FileSize - Current.BytesDownloaded)) / (float)(Current.BytesDownloaded - BeginDownloadBytes)) ); CurrentDownloadProgress.RemainTime = RemainTime.ToString(); CurrentDownloadProgress.Type = DownloadMessageType.DownloadProgressShow; SygnalEventProgress(CurrentDownloadProgress); if (TimeDifference.TotalSeconds >= 5) { BeginTime = DateTime.Now; BeginDownloadBytes = Current.BytesDownloaded; } } ; BufferOffset = 0; LastTimeDifferenceSeconds = TimeDifference.TotalSeconds; } } else {// была задана пауза CurrentDownloadProgress.Type = DownloadMessageType.DownloadPaused; SygnalEventProgress(CurrentDownloadProgress); Thread.Sleep(500); } if (ReadData == 0) { // все закачали if (Current.FileSize == -1) { // не был известен размер файла Current.FileSize = Current.BytesDownloaded; } break; } } } catch (Exception ex) { TempEx = ex; // ErrorWork(new Exception("Размер файла " + Current.FileSize)); } finally { WriteStream.Close(); // финальное состояние CurrentDownloadProgress.DownloadSize = Math.Max(Current.BytesDownloaded, Current.FileSize); CurrentDownloadProgress.Bytes = Current.BytesDownloaded; CurrentDownloadProgress.Type = DownloadMessageType.DownloadProgressShow; SygnalEventProgress(CurrentDownloadProgress); if (DownloadFileThreadRunning && Current.FileSize == Current.BytesDownloaded) { // файл закончен CurrentDownloadProgress.Type = DownloadMessageType.DownloadFinished; SygnalEventProgress(CurrentDownloadProgress); Current.FileDownloaded = true; } else { // была нажата кнопка стоп -поэтому - ничего не вызываем CurrentDownloadProgress.Type = DownloadMessageType.DownloadStopped; CurrentDownloadProgress.AdditionalInfo = "DownloadFileThreadRunning " + DownloadFileThreadRunning.ToString() + " Current.FileSize = " + Current.FileSize.ToString() + " Current.BytesDownloaded = " + Current.BytesDownloaded.ToString(); SygnalEventProgress(CurrentDownloadProgress); } DownloadFileThreadRunning = false; } if (TempEx != null) { throw TempEx; } }
private void _SaveSfxStub(string exeToGenerate, SelfExtractorSaveOptions options) { string nameOfIconFile = null; string stubExe = null; string unpackedResourceDir = null; string tmpDir = null; try { if (File.Exists(exeToGenerate)) { if (Verbose) { StatusMessageTextWriter.WriteLine("The existing file ({0}) will be overwritten.", exeToGenerate); } } if (!exeToGenerate.EndsWith(".exe")) { if (Verbose) { StatusMessageTextWriter.WriteLine("Warning: The generated self-extracting file will not have an .exe extension."); } } // workitem 10553 tmpDir = TempFileFolder ?? Path.GetDirectoryName(exeToGenerate); stubExe = GenerateTempPathname(tmpDir, "exe"); // get the Ionic.Zip assembly Assembly a1 = typeof(ZipFile).Assembly; using (var csharp = new Microsoft.CSharp.CSharpCodeProvider (new Dictionary <string, string>() { { "CompilerVersion", "v2.0" } })) { // The following is a perfect opportunity for a linq query, but // I cannot use it. DotNetZip needs to run on .NET 2.0, // and using LINQ would break that. Here's what it would look // like: // // var settings = (from x in SettingsList // where x.Flavor == flavor // select x).First(); ExtractorSettings settings = null; foreach (var x in SettingsList) { if (x.Flavor == options.Flavor) { settings = x; break; } } // sanity check; should never happen if (settings == null) { throw new BadStateException(String.Format("While saving a Self-Extracting Zip, Cannot find that flavor ({0})?", options.Flavor)); } // This is the list of referenced assemblies. Ionic.Zip is // needed here. Also if it is the winforms (gui) extractor, we // need other referenced assemblies, like // System.Windows.Forms.dll, etc. var cp = new System.CodeDom.Compiler.CompilerParameters(); cp.ReferencedAssemblies.Add(a1.Location); if (settings.ReferencedAssemblies != null) { foreach (string ra in settings.ReferencedAssemblies) { cp.ReferencedAssemblies.Add(ra); } } cp.GenerateInMemory = false; cp.GenerateExecutable = true; cp.IncludeDebugInformation = false; cp.CompilerOptions = ""; Assembly a2 = Assembly.GetExecutingAssembly(); // Use this to concatenate all the source code resources into a // single module. var sb = new System.Text.StringBuilder(); // In case there are compiler errors later, we allocate a source // file name now. If errors are detected, we'll spool the source // code as well as the errors (in comments) into that filename, // and throw an exception with the filename. Makes it easier to // diagnose. This should be rare; most errors happen only // during devlpmt of DotNetZip itself, but there are rare // occasions when they occur in other cases. string sourceFile = GenerateTempPathname(tmpDir, "cs"); // // debugging: enumerate the resources in this assembly // Console.WriteLine("Resources in this assembly:"); // foreach (string rsrc in a2.GetManifestResourceNames()) // { // Console.WriteLine(rsrc); // } // Console.WriteLine(); // all the source code is embedded in the DLL as a zip file. using (ZipFile zip = ZipFile.Read(a2.GetManifestResourceStream("Ionic.Zip.Resources.ZippedResources.zip"))) { // // debugging: enumerate the files in the embedded zip // Console.WriteLine("Entries in the embbedded zip:"); // foreach (ZipEntry entry in zip) // { // Console.WriteLine(entry.FileName); // } // Console.WriteLine(); unpackedResourceDir = GenerateTempPathname(tmpDir, "tmp"); if (String.IsNullOrEmpty(options.IconFile)) { // Use the ico file that is embedded into the Ionic.Zip // DLL itself. To do this we must unpack the icon to // the filesystem, in order to specify it on the cmdline // of csc.exe. This method will remove the unpacked // file later. System.IO.Directory.CreateDirectory(unpackedResourceDir); ZipEntry e = zip["zippedFile.ico"]; // Must not extract a readonly file - it will be impossible to // delete later. if ((e.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { e.Attributes ^= FileAttributes.ReadOnly; } e.Extract(unpackedResourceDir); nameOfIconFile = Path.Combine(unpackedResourceDir, "zippedFile.ico"); cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", nameOfIconFile); } else { cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", options.IconFile); } cp.OutputAssembly = stubExe; if (options.Flavor == SelfExtractorFlavor.WinFormsApplication) { cp.CompilerOptions += " /target:winexe"; } if (!String.IsNullOrEmpty(options.AdditionalCompilerSwitches)) { cp.CompilerOptions += " " + options.AdditionalCompilerSwitches; } if (String.IsNullOrEmpty(cp.CompilerOptions)) { cp.CompilerOptions = null; } if ((settings.CopyThroughResources != null) && (settings.CopyThroughResources.Count != 0)) { if (!Directory.Exists(unpackedResourceDir)) { System.IO.Directory.CreateDirectory(unpackedResourceDir); } foreach (string re in settings.CopyThroughResources) { string filename = Path.Combine(unpackedResourceDir, re); ExtractResourceToFile(a2, re, filename); // add the file into the target assembly as an embedded resource cp.EmbeddedResources.Add(filename); } } // add the Ionic.Utils.Zip DLL as an embedded resource cp.EmbeddedResources.Add(a1.Location); // file header sb.Append("// " + Path.GetFileName(sourceFile) + "\n") .Append("// --------------------------------------------\n//\n") .Append("// This SFX source file was generated by DotNetZip ") .Append(ZipFile.LibraryVersion.ToString()) .Append("\n// at ") .Append(System.DateTime.Now.ToString("yyyy MMMM dd HH:mm:ss")) .Append("\n//\n// --------------------------------------------\n\n\n"); // assembly attributes if (!String.IsNullOrEmpty(options.Description)) { sb.Append("[assembly: System.Reflection.AssemblyTitle(\"" + options.Description.Replace("\"", "") + "\")]\n"); } else { sb.Append("[assembly: System.Reflection.AssemblyTitle(\"DotNetZip SFX Archive\")]\n"); } if (!String.IsNullOrEmpty(options.ProductVersion)) { sb.Append("[assembly: System.Reflection.AssemblyInformationalVersion(\"" + options.ProductVersion.Replace("\"", "") + "\")]\n"); } // workitem string copyright = (String.IsNullOrEmpty(options.Copyright)) ? "Extractor: Copyright © Dino Chiesa 2008-2011" : options.Copyright.Replace("\"", ""); if (!String.IsNullOrEmpty(options.ProductName)) { sb.Append("[assembly: System.Reflection.AssemblyProduct(\"") .Append(options.ProductName.Replace("\"", "")) .Append("\")]\n"); } else { sb.Append("[assembly: System.Reflection.AssemblyProduct(\"DotNetZip\")]\n"); } sb.Append("[assembly: System.Reflection.AssemblyCopyright(\"" + copyright + "\")]\n") .Append(String.Format("[assembly: System.Reflection.AssemblyVersion(\"{0}\")]\n", ZipFile.LibraryVersion.ToString())); if (options.FileVersion != null) { sb.Append(String.Format("[assembly: System.Reflection.AssemblyFileVersion(\"{0}\")]\n", options.FileVersion.ToString())); } sb.Append("\n\n\n"); // Set the default extract location if it is available string extractLoc = options.DefaultExtractDirectory; if (extractLoc != null) { // remove double-quotes and replace slash with double-slash. // This, because the value is going to be embedded into a // cs file as a quoted string, and it needs to be escaped. extractLoc = extractLoc.Replace("\"", "").Replace("\\", "\\\\"); } string postExCmdLine = options.PostExtractCommandLine; if (postExCmdLine != null) { postExCmdLine = postExCmdLine.Replace("\\", "\\\\"); postExCmdLine = postExCmdLine.Replace("\"", "\\\""); } foreach (string rc in settings.ResourcesToCompile) { using (Stream s = zip[rc].OpenReader()) { if (s == null) { throw new ZipException(String.Format("missing resource '{0}'", rc)); } using (StreamReader sr = new StreamReader(s)) { while (sr.Peek() >= 0) { string line = sr.ReadLine(); if (extractLoc != null) { line = line.Replace("@@EXTRACTLOCATION", extractLoc); } line = line.Replace("@@REMOVE_AFTER_EXECUTE", options.RemoveUnpackedFilesAfterExecute.ToString()); line = line.Replace("@@QUIET", options.Quiet.ToString()); if (!String.IsNullOrEmpty(options.SfxExeWindowTitle)) { line = line.Replace("@@SFX_EXE_WINDOW_TITLE", options.SfxExeWindowTitle); } line = line.Replace("@@EXTRACT_EXISTING_FILE", ((int)options.ExtractExistingFile).ToString()); if (postExCmdLine != null) { line = line.Replace("@@POST_UNPACK_CMD_LINE", postExCmdLine); } sb.Append(line).Append("\n"); } } sb.Append("\n\n"); } } } string LiteralSource = sb.ToString(); #if DEBUGSFX // for debugging only string sourceModule = GenerateTempPathname(tmpDir, "cs"); using (StreamWriter sw = File.CreateText(sourceModule)) { sw.Write(LiteralSource); } Console.WriteLine("source: {0}", sourceModule); #endif var cr = csharp.CompileAssemblyFromSource(cp, LiteralSource); if (cr == null) { throw new SfxGenerationException("Cannot compile the extraction logic!"); } if (Verbose) { foreach (string output in cr.Output) { StatusMessageTextWriter.WriteLine(output); } } if (cr.Errors.Count != 0) { using (TextWriter tw = new StreamWriter(sourceFile)) { // first, the source we compiled tw.Write(LiteralSource); // now, append the compile errors tw.Write("\n\n\n// ------------------------------------------------------------------\n"); tw.Write("// Errors during compilation: \n//\n"); string p = Path.GetFileName(sourceFile); foreach (System.CodeDom.Compiler.CompilerError error in cr.Errors) { tw.Write(String.Format("// {0}({1},{2}): {3} {4}: {5}\n//\n", p, // 0 error.Line, // 1 error.Column, // 2 error.IsWarning ? "Warning" : "error", // 3 error.ErrorNumber, // 4 error.ErrorText)); // 5 } } throw new SfxGenerationException(String.Format("Errors compiling the extraction logic! {0}", sourceFile)); } OnSaveEvent(ZipProgressEventType.Saving_AfterCompileSelfExtractor); // Now, copy the resulting EXE image to the _writestream. // Because this stub exe is being saved first, the effect will be to // concatenate the exe and the zip data together. using (System.IO.Stream input = System.IO.File.OpenRead(stubExe)) { byte[] buffer = new byte[4000]; int n = 1; while (n != 0) { n = input.Read(buffer, 0, buffer.Length); if (n != 0) { WriteStream.Write(buffer, 0, n); } } } } OnSaveEvent(ZipProgressEventType.Saving_AfterSaveTempArchive); } finally { try { if (Directory.Exists(unpackedResourceDir)) { try { Directory.Delete(unpackedResourceDir, true); } catch (System.IO.IOException exc1) { StatusMessageTextWriter.WriteLine("Warning: Exception: {0}", exc1); } } if (File.Exists(stubExe)) { try { File.Delete(stubExe); } catch (System.IO.IOException exc1) { StatusMessageTextWriter.WriteLine("Warning: Exception: {0}", exc1); } } } catch (System.IO.IOException) { } } return; }
protected sealed override void Write(byte[] s) { WriteStream.Write(s, 0, s.Length); }