am sorry but I don't know where to start
I need a way to use files from zip file in real time as they get unziped
like to write from file stream
the console app is a samsung odin flash program
and the arguments to it like
odin --flash --recovery /recovery.img path --boot /boot.img path etc
and unziping samsung firmware files take too much duo to large size of some of the files in it
so am looking for a way to make the argument go like
odin --flash --recovery 'stream providing the recovery.img file as it unzip'
I don't know if that possible but I hope there is a way to do that
I didn't try any thing because I don't know where to start
That's not possible because odin expects a file name, not a stream of data.
If you wanted to print a decompressed file from a .zip to the console, you'd do something like this:
using System.IO.Compression;
using System.Text;
static void PrintZipFile(string zipPath, int fileIndex)
{
using var zip = ZipFile.OpenRead(zipPath);
using Stream firstEntry = zip.Entries[fileIndex].Open();
using var r = new BinaryReader(firstEntry);
Console.WriteLine(Encoding.ASCII.GetString(r.ReadBytes((int)r.BaseStream.Length)));
}
Related
Can a running .NET .EXE append data to itself? What's stopping it?
I could launch a separate process to do it just fine.
But I can't figure out how to write to itself while it's running. Is there anyway to do this? IN .NET
EDIT: And preferably no hacky solutions like write it out somewhere else then copy/rename
EDIT2: Clarifying type of executeable
EDIT3: Purpose: Writing binary stream to my running EXE file allows me to then parse the .EXE file on disk for those bytes and use them in the program. Without having to create any new files or registry entries or stuff like that. It is self contained. This is extremely convenient.
EDIT4: For those against this file, please thinking about the functions of: FILE ZIPPING, DLL LINKING, and PORTABLE APPLICATIONS before trying to discredit this idea,
There are a lot of bad consequences for storing data this way, as said in the comments, but there's a bigger problem: the answer to "What's stopping it?" question. The Windows PE loader locks the image file for writing while in execution, so you can't get an HANDLE to the file with write permissions, as NtCreateFile and NtOpenFile system calls with FILE_WRITE_DATA option will fail, as well as any attempt to delete the file. This block is implemented at kernel level and set during the NtCreateProcess system call, before the process and its modules entry point are actually called.
The only dirty trick possible without writing data to the disk, sending it to a remote server and without kernel privileges is to use another process via an helper executable, code injection or command-line arguments scripts (e.g. with PowerShell) which can kill your process releasing the lock, append data to the end of file and restart it. Of course these options have even worse consequences, I wrote it only to make clear the OS limitations (made by purpose) and why no professional software uses this technique to store data.
EDIT: since you are so determined to accomplish this behavior I post a proof of concept for appending data via helper executable (file copy), the method relies on executing a new copy of the image in TEMP folder, passing the path to the original executable so it can be "written" because isn't running and locked. FOR READERS I SUGGEST TO DON'T USE IT IN PRODUCTION
using System;
using System.IO;
using System.Reflection;
using System.Diagnostics;
namespace BadStorage
{
class Program
{
static void Main(string[] args)
{
var temp = Path.GetTempPath();
var exePath = Assembly.GetExecutingAssembly().Location;
if (exePath.IndexOf(temp, StringComparison.OrdinalIgnoreCase) >= 0 && args.Length > 0)
{
// "Real" main
var originalExe = args[0];
if (File.Exists(originalExe))
{
// Your program code...
byte[] data = { 0xFF, 0xEE, 0xDD, 0xCC };
// Write
using (var fs = new FileStream(originalExe, FileMode.Append, FileAccess.Write, FileShare.None))
fs.Write(data, 0, data.Length);
// Read
using (var fs = new FileStream(originalExe, FileMode.Open, FileAccess.Read, FileShare.Read))
{
fs.Seek(-data.Length, SeekOrigin.End);
fs.Read(data, 0, data.Length);
}
}
}
else
{
// Self-copy
var exeCopy = Path.Combine(temp, Path.GetFileName(exePath));
File.Copy(exePath, exeCopy, true);
var p = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = exeCopy,
Arguments = $"\"{exePath}\"",
UseShellExecute = false
}
};
p.Start();
}
}
}
}
Despite all the negativity, there is a clean way to do this:
The way I have found only requires the program be executed on an NTFS drive.
The trick is to have your app copy itself to an alternate stream as soon as it's launched, then execute that image and immediately close itself. This can be easily done with the commands:
type myapp.exe > myapp.exe:image
forfiles /m myapp.exe /c myapp.exe:image
Once your application is running from an alternate stream (myapp.exe:image), it is free to modify the original file (myapp.exe) and read the data that's stored within it. The next time the program starts, the modified application will be copied to the alternate stream and executed.
This allows you to get the effect of an executable writing to itself while running, without dealing with any extra files and allows you to store all settings within a single .exe file.
The file must be executed on an NTFS partition, but that is not a big deal since all Windows installations use this format. You can still copy the file to other filesystems, you just cannot execute it there.
When someone print a document(with XPS printing path) I want to pause print job and edit SPL(which zipped XPS format) file.
If I edit the file with 7zip and save. If I resume the job that document printing without any problem.
If I open the SPL file with System.IO.Compression.ZipFile class or DotNetZip library or SevenZipSharp library and extract a file from SPL file & remove that filefrom SPL file and add that file again to SPL file it generates perfectly fine zip container. I compared the original SPL file and edited SPL file with 7zip, zipinfo, winrar tools and I didn't see any difference. All files in the container are exactly same. I also checked CRCs.
When I'm opening,editing and saving the zipfile I'm not changing anything about compression method, compression level and etc. As I said two zip files looks like exactly same but If I calculate CRCs of original and edited SPL files they are not same.
After I edited(just extracting a page file, deleting it from container and adding it again to container) If I try to resume print job I see an error in event viewer about PrintProcessor and I can't print it.
I can't figure out what's changing after I edit the file(not changing anything in container). I'm going crazy.
Is there any specification about the Zip format of SPL files?
Problem solves If I use "ZipPackage" class.
using (var pack = ZipPackage.Open(xpsFileName, FileMode.Open, FileAccess.ReadWrite))
{
foreach (var part in pack.GetParts()) if (part.Uri.OriginalString.EndsWith(".fpage"))
{
using (var file = part.GetStream(FileMode.Open, FileAccess.ReadWrite))
{
var page = ProcessPage(XElement.Load(file));
file.Position = 0;
page.Save(file);
file.SetLength(file.Position);
}
}
}
I'm sure this has been done before and is probably quite simple to achieve but I can't seem to find anything on the internet when I've searched.
I'm looking for a way to pickup/copy a file from my applications resources and place it into a folder on my the C: drive. Can this be done? Or should I read in the contents of the file and then create a new one in the desired directory?Any pointers/advice would be appreciated! Thanks.
You can take the contents of the embedded file and write them out to your desired location as follows:
using (var fs = new FileStream(#"C:\Temp\Foo.txt", FileMode.Create))
using (var sw = new StreamWriter(fs))
{
var data = Stuff.Foo;
sw.Write(data);
}
I did this for a text file embedded in Stuff.resx in my project. There's a Write overload for various types so you can use what you need. For instance, an image will come back as a bitmap.
I achieved this by using File.WriteAllBytes()
Example:
File.WriteAllBytes("C:\\MyApp\\TextExample.json", MyApp.Properties.Resources.TextExample);
I'm new to programming so please be patient.
I am currently developing a small Program in Visual C# 2010 Express, .NET Framework 4.0, which starts a Script on a Linux Machine (what creates the File /tmp/logs.tgz), downloads the File and then I want to extract it. Running the Script and downloading the File via Renci.SshNet works flawlessly.
But when I want to extract it, it gives me an Error "NotSupportedException" my Filepath Format is incorrect (which is not the case, I think?).
I copy and pasted the Code directly from here (Simple full extract from a TGZ (.tar.gz)) and edited it for my Needs:
using System.IO;
using System.IO.Compression;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
//it executed the Script and created the file on the Linux Machine /tmp/logs.tgz
//now I want to download it
string myTime = DateTime.Now.ToString("yyyyMMdd");
var pathWithEnv = (#"%USERPROFILE%\Desktop\logs" + myTime + ".tgz");
var filePath = Environment.ExpandEnvironmentVariables(pathWithEnv);
string localFile = filePath;
//then downloads /tmp/logs.tgz to ..\Desktop\logs+ myTime +.tgz
//everything great until now. here I want to extract .TGZ:
var pathWithEnv2 = (#"%USERPROFILE%\Desktop\logs" + myTime);
var fileDir = Environment.ExpandEnvironmentVariables(pathWithEnv2);
string localDir = fileDir;
Stream inStream = File.OpenRead(localFile);
Stream gzipStream = new GZipInputStream(inStream);
TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
//ERROR OCCURS HERE:
tarArchive.ExtractContents(localDir);
tarArchive.Close();
gzipStream.Close();
inStream.Close();
I even tried to set the localFile and localDir string without the EnviromentVariable, but that didnt help. I tried:
- download and extract it directly on C:\ (or on a mapped Network Drive U:) to prevent too long filenames (which should not be the case as it should never get longer than 86 characters).
- string = #"C:..\logs", string = "C:\..\logs", string = #"C:..\logs\", etc.
- tried it without myTime
- using ICSharpCode.SharpZipLib.Core;
I did a MessageBox.Show(localDir); before the tarArchive.ExtractContents(localDir); and it showed "C:\Users\Baumann\Desktop\logs20140530" which is correct, thats the Directory I want to extract it to. Even creating the Directory before executing it doesn't help.
I also created a new Project with just one button which should start the Extraction and the same error occurs.
I tried, doing it separately, first extract the GZip and then the .tar, but it also gives me the same Error when extracting the GZip (using ICSharpCode.SharpZipLib.Core; of course).
What drives me even more crazy about it, is, that it starts to extract it, but not everything, before it fails. And always the same Files, whats not clear for me why these and why not the others.
I'm on Windows 8.1, using SharpZipLib 0.86.0.518, downloaded directly from the Website.
Thanks in advance.
well, I finally fixed the Problem. The Linux machine is creating a file which includes the MAC-Adress and since Windows can't handle ":" in a Filename, it crashes.
I am now extracting file by file and checking each file for ":" and replacing it with "_", works flawlessly.
I've got 100's (maybe 1000's) of products with 10-30 images of each product coming to an online store I've put together. I need to optimize the images' file sizes as much as possible without loosing image quality.
I haven't used jpegtran, jpegoptim, or any other jpeg optimizer directly but I have noticed that punypng shrinks file sizes down about 4-6% on the larger jpeg images LOSSLESSLY.
Meta data is already stripped from the images during upload (via jumpoader) so that is not an option/problem anymore.
Is there any way to get one of the jpeg optimizers to run from C# code?
Note: I'm using shared Godaddy hosting with IIS7 and .Net 3.5
It might be 7 years too late, but I came across this question while trying to solve this problem. I eventually managed to do it and this is the solution.
For PNG you first need to install nQuant using NuGet.
include:
using System.Web.Hosting;
using System.IO;
using System.Diagnostics;
using nQuant;
using System.Drawing;
using System.Drawing.Imaging;
Methods:
public void optimizeImages()
{
string folder =
Path.Combine(HostingEnvironment.ApplicationPhysicalPath, #"assets\temp");
var files = Directory.EnumerateFiles(folder);
foreach (var file in files)
{
switch (Path.GetExtension(file).ToLower())
{
case ".jpg":
case ".jpeg":
optimizeJPEG(file);
break;
case ".png":
optimizePNG(file);
break;
}
}
}
private void optimizeJPEG(string file)
{
string pathToExe = HostingEnvironment.MapPath("~\\adminassets\\exe\\") + "jpegtran.exe";
var proc = new Process
{
StartInfo =
{
Arguments = "-optimize \"" + file + "\" \"" + file + "\"",
FileName = pathToExe,
UseShellExecute = false,
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardError = true,
RedirectStandardOutput = true
}
};
Process jpegTranProcess = proc;
jpegTranProcess.Start();
jpegTranProcess.WaitForExit();
}
private void optimizePNG(string file)
{
string tempFile = Path.GetDirectoryName(file) + #"\temp-" + Path.GetFileName(file);
int alphaTransparency = 10;
int alphaFader = 70;
var quantizer = new WuQuantizer();
using (var bitmap = new Bitmap(file))
{
using (var quantized = quantizer.QuantizeImage(bitmap, alphaTransparency, alphaFader))
{
quantized.Save(tempFile, ImageFormat.Png);
}
}
System.IO.File.Delete(file);
System.IO.File.Move(tempFile, file);
}
It will take all files from /assets/temp folder and optimize jpegs and PNG.
I followed this question for the png part. The jpeg part I scraped from several sources. Including PicJam and Image Optimizer. The way I use it is by uploading all files from the user to the temp folder, running this method, uploading the files to azure blob storage, and deleting the local files. I downloaded jpegtran here.
If you don't like to mess with temporary files, I'd advise to use C++/CLI.
Create a C++/CLI dll project in visual studio. Create one static managed class, and define the functions as you want to use them from C#:
public ref class JpegTools
{
public:
static array<byte>^ Optimize(array<byte>^ input)
};
These functions you define can be directly called from C#, and you can implement them with all that C++ offers.
array^ corresponds to a C# byte array. You'll need to use pin_ptr<> to pin the byte array in memory, so you can pass on the data to the unmanaged Jpeg helper function of your choice. C++/CLI has ample support for marshalling managed types to native types. You can also allocate new array with gc_new, to return CLI compatible types. If you have to marshall strings from C# to C++ as part of this excercise, use Mfc/Atl's CString type.
You can statically link all the jpeg code into the dll. A C++ dll can be mixed pure native and C++/CLI code. In our C++/CLI projects, typically only the interface source files know about CLI types, all the rest work with with C++ types.
There's some overhead work to get going this way, but the upside is that your code is compile-time typechecked, and all the dealings with unmanged code and memory are dealt with on the C++ side. It actually works so well that I used C++/CLI to unit test native C++ code almost directly with NUnit.
Good luck!
I would batch process the images before uploading them to your web server, rather then try to process them while serving them. This will lead to less load on the web server and let you use any match image processing tools you wish.
I'm sure that I'm totally late to answer this question, but recently I have faced on lossless jpeg optimization problem and haven't found any suitable C# implementation of jpegtran utility. So, I have decided to implement by myself routines for lossless jpeg size reducing based on C wrapper of modified jpegtran, which you can find here. It comes, that similar realization with use of pure .Net LibJpeg.NET is far more slower than C wrapped solution, so, I haven't included it to the repo. Using of wrapper is quite simple,
if (JpegTools.Transform(jpeg, out byte[] optimized, copy: false, optimize: true))
{
//do smth useful
}
else
{
//report on error or use original jpeg
}
Hope, someone will find it useful.
Why not call punypng.com with Process.Start()? There is no reason why you .net code can't run external programs, provided the processing is done at the time of uploading (rather then when serving the images)
E.g.
upload into a "upload" folder,
have a windows services that watches for new files in the “upload” folder
when you get a new file, start punypng.com to process it and put the output into the correct image folder.