Create a pipe file in windows/.net - c#

I am using an older program that generates it's output into a file. I can specify on the command line the file to use, but it must go to a file (no option to send to stdout).
I would like to stream that output as it is generated (not wait until the file is finished). In *nix, I would create a named pipe, and use that "file" as the output.
Can this (or something similar) be done in Windows? Can it be done in pure C#, or only c/c++/pInvoke? Is there some library that can do this cross platform?

From your .Net application, you can spawn the legacy application as a Process, for which you can define, among other things, its standard output stream. You can use a file stream or any other kind of stream to redirect the process's output.

Related

C#, can I save a file from a stream or other to my single exe?

I would like to take a serialized file and save it to my recourses folder in project.
My reason for doing this (maybe there's a better way) is I have a published exe (single executable file) for the program that runs and when it creates a serialized file I don't want it to save it to desktop. I need to somehow save it to my exe without going outside of it.
Any advice on how I could do this?
It's very ugly.....but you could use an "alternative data stream" on NTFS system.
http://ntfs.com/ntfs-multiple.htm
https://learn.microsoft.com/en-us/sysinternals/downloads/streams
How to read and modify NTFS Alternate Data Streams using .NET
https://blogs.msmvps.com/bsonnino/2016/11/24/alternate-data-streams-in-c/
https://oddvar.moe/2018/04/11/putting-data-in-alternate-data-streams-and-how-to-execute-it-part-2/
https://blog.foldersecurityviewer.com/ntfs-alternate-data-streams-the-good-and-the-bad/
https://www.irongeek.com/i.php?page=security/altds
You'll probably have security scanners stopping you from doing it.
In addition if you copy the from an NTFS volume to say FAT, then alternative data streams are lost.
Also some backup software may not backup ADS properly.
https://wiki.sep.de/wiki/index.php/Support_for_NTFS_alternate_data_streams_(ADS)_for_Windows
https://www.2brightsparks.com/resources/articles/ntfs-alternate-data-stream-ads.html
https://community.osr.com/discussion/89308/alternate-data-streams-and-backups
https://social.technet.microsoft.com/Forums/Azure/en-US/007d5442-1cd8-4293-b717-b8fa72606189/ntfs-data-streams-broken-by-design-on-file-copy?forum=winserverfiles

Unable to save to nul device from ASP.net app

I am having a spot of bother trying to save a dummy file to the nul device in an ASP.Net (.Net 4.5.2) application. When I get the the point where the application tries to save the file, it throws an exception.
The file's path is set to "nul" (sic), and when it is saved I get the following exception message:
Access denied to file "\\\\.\\nul"
Is it possible using .Net (C# in my case) to save a file to the nul device from within a web application?
In case you are wondering, saving the file is merely a trigger for another action. I am not interested in the saved file itself, and I want to avoid the code overhead of having to create and later delete a uniquely named dummy file - hence saving it to the nul device.
TIA
This answer on MSDN suggests you can't do this with the .NET file handling API:
While the Win32 CreateFile method will open devices, alternate streams, etc, somewhere along the line it was decided that the .Net File implementation would be restricted to traditional files. Probably not what you wanted to hear.
social.msdn.microsoft.com/Forums/vstudio/en-US/43163abb-4e82-4a7d-b614-29eb7914bdba/nul-filename-in-net
use the flag that deletes filestream on close...
new FileStream(TempFileName,
FileMode.CreateNew,
FileAccess.ReadWrite,
FileShare.ReadWrite, 512,
FileOptions.DeleteOnClose);

Use a stream as file?

I am working on a telephony application using a third party library to send audio across the wire.
This third party library only accepts a very specific wav format, and takes in the file as a filename path on disk. Our current audio files are not in this format. I can use NAudio to convert from our legacy format to this new format.
However, I don't really want two sets of audio files floating around.
What I basically want to do is take an NAudio.WaveStream and be able to pass it to the third party library without writing it to disk, because the library takes a path to a filename. If performance is bad, I will be forced to have multiple sets of audio files, but I would like to avoid this. I am not even sure what terms to Google.
Is this a use case for memory mapped files?
Probably not worth your while but if you're absolutely stuck with the 3rd party app and are against writing to disk you could create a virtual drive using a library like http://dokan-dev.net/en/. You could intercept the requests from the 3rd party app and stream the converted files to it as they were needed.
Saying that, I would probably take the hit on writing the files to a normal drive.
If nothing else it'll kick off your searches.

Downloading and running a JAR from memory in .NET

I have a C# application, where I need to download and run a JAR file, without it being saved to disk. Is this possible in C#? I can download files via WebClient just fine to disk (which is what I'm doing as of posting) & launch it via a batch script which is saved then deleted, but I want to take it a step further by not having anything touch the drive.
Thanks.
You could write a special Java class loader that loads classes via interprocess communication (IPC) from the .NET process instead of from a file. In addition, you'll need a small launcher JAR that first installs the class loader and then executes the JAR retrieved via IPC. And you'll need to implement the server part of the IPC communication in your .NET application.
But is it worth it? What would be the benefit of such a complex piece of software?
A JAR file needs to executed by javaw.exe, the JVM. Another process doesn't have the power to reach into your virtual memory space and read the file data. Not unless both processes co-operate and use a shared memory section. You get no such co-operation from javaw.exe, it requires a file.
This is a non-issue in Windows since javaw.exe will actually read the file from memory. When you write the file in your program, you actually write to the file system cache. Which buffers file data in RAM, delay-writing it to the disk. As long as the file isn't to big (gigabyte or more) and you don't wait too long to start java (minutes) and the machine has enough RAM (gigabyte or two) then javaw.exe reads the file from the file system cache. RAM, not disk. Exact same idea as a RAM-disk of old.

Save data in executable

I have a portable executable that saves data to a file in the same folder as the executable. Is there any way that I can save data into the executable itself when I close the app?
This maybe weird, but taking the data with me and only have one file for the exe and data would be great.
Would prefer if this was made with C#, but is not a requisite.
You cannot modify your own EXE to contain stored data in anything approaching an elegant or compact way. First off, the OS obtains a lock on the EXE file while the application contained within is being run. Second, an EXE comes pre-compiled (into MSIL at least), and modification of the file's source data usually requires recompilation to reset various pointers to code handles, or else a SERIOUS knowledge on a very esoteric level about what you're doing to the file.
The generally-accepted methods are the application config file, a resource file, or some custom file you create/read/modify at runtime, like you're doing now. Two files for an application should not be cause for concern
You can, by reserving space through the means of using a string resource and pad it out. You need to do a bit of detective work to find out exactly where in the offset to the executable you wish to dump the data into, but be careful, the file will be "in use", so proceed cautiously with that.
So right now you're using an app.config (and Settings.settings) file?
I believe this is the most compact way to save data close to the .exe.
I would highly doubt you can alter the manifest of the .exe, or any other part of it.
Edit: Apparently, there might be some ways after all: http://www.codeproject.com/KB/msil/reflexil.aspx
There is one way using multiple streams, but only works in NTFS filesystems.
NTFS allows you to define alternative "named" streams in one file. The usual content is in the main = unnamed stream. It has something to do with the extra info you can see when you right click a file and check properties.
Unfortunatly C# has no support for multiple streams, but there are open source pojects that can help you.
See this link for a nice wrapper to read and write multiple streams to one single file in C#
Alternate data streams might work. By using the ::stream syntax you can create a data stream within your exe and read/write data.
Edit:
to create/access an alternate data stream, you will use a different filename. Something like:
applicAtion.exe:settings:$data
this will access a data stream named "settings" within application.exe. To do this you need to add the :settings:$data to the filename when reading or writing to the file. This functionality is provided by ntfs so it shold work in c# and should work when the application is running.
Additional information is available at: http://msdn.microsoft.com/en-us/library/aa364404(VS.85).aspx
If you want to take the data with you and only have one file for the exe and data, .zip them into a self-extracting .exe.
you can add data to end of executable file :
var executableName = Process.GetCurrentProcess().MainModule.FileName;
// rename executable file
var newExecutableName = fullPath.Replace(".exe", "_.exe");
FileInfo fi = new FileInfo(executableName);
fi.MoveTo(newExecutableName);
// make copy of executable file to original name
File.Copy(newExecutableName, executableName);
// write data end of new file
var bytes = Encoding.ASCII.GetBytes("new data...");
using (FileStream file = File.OpenWrite(executableName))
{
file.Seek(0, SeekOrigin.End);
file.Write(bytes, 0, bytes.Length);
}
// we can delete old file when exited

Categories