I have a general question concerning C# & Windows API:
My task is loading a file from a document management system (DMS) and create a byte array from this file. From the developer of the DMS I got a dll which provides a method like this:
loadFile(int DocId, string PathToSaveFile);
Unfortunately the given dll does not provide me a method to deliver the requested file as a byte array or any kind of stream. Now my question, is it possible with C# to create some kind of virtual path which does actually not exists on secondary storage. Instead all bits and bytes written to this path are forwarded to me in a stream? The goal of my intention is to increase the performance as I don't have to write data to a hard drive.
I already searched a lot, but actually don't know the keywords I have to look for. Perhaps someone can give me a hint or just tell me that it is not possible at all.
It will depend somewhat on how the library will open the file and read the file. If it is using CreateFile then there is the potential that you could provide access via a named pipe. The path to a named pipe can be specified using \\.\pipe\PipeNameHere. In C# you can use NamedPipeServerStream.
However, I think the odds of the client application being compatible with this are relatively slim and would suggest creating a RAM drive that will be easier to implement and is more likely to work. A RAM drive will appear as a normal disk drive. You can save and load files to it, but it is all done in memory.
Related
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
I'm looking for a way to join separate audio and video streams into a single container.
Specifically I have VP8 video (webm container) and 16-bit PCM audio (wav container), which I'd like to combine into a Matroska container.
So far I can achieve this by saving the streams to files, and calling ffmpeg.exe by using the Process API which produces the result I need, but I'd prefer a solution that doesn't rely on saving the intermediate files to disk or requiring the ffmpeg.exe to be on the server. Any help much appreciated!
You would need a managed Matroska/WebM library, or at least a managed wrapper to some native library if you want to avoid the additional process. I'm not aware of any that exist/are up-to-date. I started writing one a few years ago but never completed it.
On launching the process, it's not actually necessary to "save files to disk", as you can use a named pipe, which "looks like a file on disk", but is in fact just an interface to some in-memory value - so you can share the memory directly with ffmpeg/mkvmerge, by passing them the name of the pipe in place of the regular filename. Can't help with not requiring the binary on the server though - other than just packaging it with your solution.
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.
I'm in a situation where I'd like to, using C#, look at .iso files that are in a directory and determine if they are indeed video discs (DVD/BD or similar).
I don't need to actually distinguish the type, just a blanket "yes this is a video disc". Is there a way to do this?
the ISO file is actually a CD Image in file format. The easiest way to determine what is on it is to mount it with a Virtual CD program. Or you can look at the file contents.
Here is the Specifications for ISO files
http://users.telenet.be/it3.consultants.bvba/handouts/ISO9960.html
After you are able to determine what information is on the disk then you can determine if there is video information on it by finding out what the contents of those files are.
That is a much more daunting task then just determining the file structure.
This specification file will only define ISO files. Other cd formats will need to be read using their own Specifications...
You can determine if the file is of type ISO using the header data
Here is a Stack Question explaining in a little more detail.
Using .NET, how can you find the mime type of a file based on the file signature not the extension
EDIT
Looking into the Mime type thing a little more reveals that Microsoft will have to have a registered mime type for that header data. It may not know that it is an ISO and may tell you application/octet-stream If this is the case then you can instead use your own judgement with the same first 256 bytes. Determine some things that tell you that it is an ISO file that you can handle. Usually you can tell what type and version a file is with the first 20 bytes or so.
I did some searching around for a library that you could use to read/write ISO files. You just need the read part obviously and this project is something you could probably use http://discutils.codeplex.com/
As another mentioned, an ISO file contains a file system. The easiest way to read it is to mount it as a virtual drive, using any one of a number of utilities. Once you've mounted it as a drive, then you can determine that it likely contains a movie by inspecting the file system (i.e. using Directory.GetFiles and similar methods in C#).
If you want to read the file's contents directly (without mounting it), I'm not sure what to tell you. I've heard that 7-zip has an API that will let you read the files. You might also check out DiscUtils, which claims to be able to read ISO files.
Once you can read the contents of the file system, see the "Filesystem" section of http://en.wikipedia.org/wiki/DVD-Video. That will tell you what files and directories you should expect to see in the ISO of a DVD movie.
Note that the files' existence is an indication that the image probably contains a DVD movie. There's no way to tell for sure without examining the files' contents individually. Tracking down the specifications for the individual file types might be a more difficult task.
try using IMAPIv2 to interrogate the iso.
This link doesnt do that.. but it should get you started in the right direction.
How to create optical ISO using IMAPIv2
I am developing an application and I would like to be able to search the whole drive for a regular expression. I would prefer to do this in c# but I can call other languages. Is there any easy way to just seek through all the binary data on a drive from begining to end?
Here's an implementation of grep in C#
http://dotnet.jku.at/applications/Grep/Src.aspx
You can modify to follow subdirectories -- it works off of an array of filenames.
AFAIK there is no simple way to do this on raw binary data (You would need direct disk control).
If file-basis is enough enumerating all files, opening them for binary shared reading (catch the exceptions for the ones that are system protected) and then looking for the data should be straightforward. However this will be quite slow as enumerating and opening all files will take some time.
I don't think C# can read all files / data for the drive the OS is on, since the OS locks some files.
You could use the System.IO namespace to enumerate all files, and then scan them individually byte by byte, this obviously would take a long time.
Do you really want to do this ? How are you going to search:
.doc
.xls
.pdf
.html
etc.? Each file type will represent the string you're searching for in different ways.
This article shows how to read data directly from the disk. Everything they do from C++ could be done from C# using PInvoke.