.NET Write a file with File Version Information attached - c#

Is there anyway to say... Include a version number when creating a text file?
Basically, my process is writing a text file that I need to check if there's a newer version available. My plan was to use FileVersionInfo to determine the current version and the version on the PC. However, I can't figure out how to write the file to the PC with a version attached to the file.
Any ideas?

Typical options here include;
hashing the contents and comparing that
relying onthe audit dates
storing version in the file and
storing version in the first line of the file
using file-watcher events (unreliable by itself, by most accounts)
using the alternative data streams in NTFS
But no; plain text files don't have much associated metadata by themselves

Plain text files have no embedded resources (except for file attributes such as the file date).
Either write the version as part of the text that can easily be parsed, use the file date to track versions, or use binary files and embed your own resources.

Related

How do I get the file version from bytes or stream?

I get the file version this way:
var fileVersion = FileVersionInfo.GetVersionInfo(path).FileVersion
But this option is not suitable for me, since I have to use a non-native tool to get the file that returns the stream. Can I get the file version from this stream or from an array of bytes?
Unfortunately, you cant do this directly
you should
Write the file to disk in some sort of temporary location
Read the version from the file on disk
Delete the file
In short, no, what you want is not possible with the current tools. The problem is that, as you've noticed, FileVersionInfo.GetVersionInfo relies on a physical file to be present on disk. If you look at its internals, you'll see that all it really does is to delegate to the Windows API which does the real work, precisely in the GetFileVersionInfo function, which in turn also takes a file name as parameter, so it's only designed to operate from the filesystem.
A possible workaround would be to drop a temp file with the binary you got from your stream, get the version info you need, then delete the file.
Another option would be to look for a library that can parse in-memory exe/dll files and extract the relevant details directly from there.

Can you pre-compress data files to be inserted into a zip file at a later time to improve performance?

As part of our installer build, we have to zip thousands of large data files into about ten or twenty 'packages' with a few hundred (or even thousands of) files in each which are all dependent on being kept with the other files in the package. (They are versioned together if you will.)
Then during the actual install, the user selects which packages they want included on their system. This also lets them download updates to the packages from our site as one large, versioned file rather than asking them to download thousands of individual ones which could also lead to them being out of sync with others in the same package.
Since these are data files, some of them change regularly during the design and coding stages, meaning we then have to re-compress all files in that particular zip package, even if only one file has changed. This makes the packaging step of our installer build take well over an hour each time, with most of that going to re-compressing things that we haven't touched.
We've looked into leaving the zip packages alone, then replacing specific files inside them, but inserting and removing large files from the middle of a zip doesn't give us that much of a performance boost. (A little, but not enough that its worth it.)
I'm wondering if its possible to pre-process files down into a cached raw 'compressed state' that matches how it would be written to the zip package, but only the data itself, not the zip header info, etc.
My thinking is if that is possible, during our build step, we would first look for any data file that doesn't have a compressed cache associated with it, and if not, we would compress that file and write the result to the cache.
Next we would simply append all of the caches together in a file stream, adding any appropriate zip header needed for the files.
This would mean we are still recreating the entire zip during each build, but we are only recompressing data that has changed. The rest would just be written as-is which is very fast since it is a straight write-to-disk. And if a data file changes, its cache is destroyed, so next build-pass it would be recreated.
However, I'm not sure such a thing is possible. Is it, and if so, is there any documentation to show how one would go about attempting this?
Yes, that's possible. The most straightforward approach would be to zip each file individually into its own associated zip archive with one entry. When any file is modified, you replace its associated zip file to keep all of those up to date. Then you can write a simple program to take a set of those single entry zip files and merge them into a single zip file. You will need to refer to the documentation in the PKZip appnote. Take a look at that.
Now that you've read the appnote, what you need to do is use the local header, data, and central header from each individual zip file, write the local header and data as is sequentially to the new zip file, and save the central header and the offsets of the local headers in the new file. Then at the end of the new file save the current offset, write a new central directory using the central headers you saved, updating the offsets appropriately, and ending with a new end of central directory record with the offset of the start of the central directory.
Update:
I decided this was a useful enough thing to write. You can get it here.
You could zip each file before hand, and then "zip" them together with no compression at the end to quickly aggregate them into a distributable package. It won't be as efficient as compressing all the data at once, but should be faster to make modifications.
I cannot seem to locate an actual exe that implements this type of functionality. It appears that most existing tools I've tried that have the ability to merge/update will reprocess(compress) the data stream as you have already stated you saw.
However it seems what you describe can be done if you or someone wants to write it. If you take a look at this link for the ZIP file format specification, you can get an overview of the structure you would have to parse out and process. It looks like you can pretty quickly go from file to file gathering up and discarding the files of interest, then merging in your new/updated files. You would still need to rebuild a new central directory (refer to section 4.3.6 of the above linked document) within your new destination archive.
After a little more digging, the DotNetZip Library forum has a message asking about the same type of functionality which also gives a description just like I described above. It also links to this document which seems to indicate that support for that may be added to the DotNetZip library for you to further experiment with.

Determine if an .iso is actually a video/movie in C#

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

Reading an STG file created from MS ActiveSync

How can I parse an STG (Microsoft ActiveSync Mobile Device Backup) file (created by ActiveSync)?
I have an old .stg file that was created from backing up an old Windows Mobile device, and I would like to write a program to read it using C#. I have tried a few things but can't get anything but garbage when I read through it. From what I can find online it is stored in Unicode format but that's about it, any posts I find talking about it are ancient and all the links are dead.
You can open ActiveSync .stg files in an archiver tool such as 7-Zip or PeaZip. If the program does not recognize the file as an archive, you may need to rename the file to have an archive extension (e.g., .7z, .gz, .tar).
With PeaZip is also possible to try to open any file extension from "Open as archive" menu entry (also available in system's context menu), without changing the file's extension.
With many format being basically variations of Deflate-compressed containers, it is worth trying.
Anyway, some formats may introduce proprietary fields (e.g. extra checksums, comments, digital signing, etc) which are out of the scope for a general-purpose archiver as PeaZip or 7-Zip.
So, while it is harmless to try to read container files as archives, it is not adviceable to try to edit them as such.

how to create a custom file extension in C#?

I need help in how to create a custom file extension in my C# app. I created a basic notes management app. Right now I'm saving my notes as .rtf (note1.rtf). I want to be able to create a file extension that only my app understands (like, note.not, maybe)
As a deployment point, you should note that ClickOnce supports file extensions (as long as it isn't in "online only" mode). This makes it a breeze to configure the system to recognise new file extensions.
You can find this in project properties -> Publish -> Options -> File Associations in VS2008. If you don't have VS2008 you can also do it manually, but it isn't fun.
File extensions are an arbitrary choice for your formats, and it's only really dependent on your application registering a certain file extension as a file of a certain type in Windows, upon installation.
Coming up with your own file format usually means you save that format using a format that only your application can parse. It can either be in plain text or binary, and it can even use XML or whatever format, the point is your app should be able to parse it easily.
There are two possible interpretations of your question:
What should be the file format of my documents?
You are saving currently your notes in the RTF format. No matter what file name extension you choose to save them as, any application that understands the RTF format will be able to open your notes, as long as the user knows that it's in RTF and points that app to that file.
If you want to save your documents in a custom file format, so that other applications cannot read them. you need to come up with code that takes the RTF stream produced by the Rich Edit control (I assume that's what you use as editor in your app) and serializes it in a binary stream using your own format.
I personally would not consider this worth the effort...
What is the file name extension of my documents
You are currently saving your documents in RTF format with .rtf file name extension. Other applications are associated with that file extension, so double-clicking on such file in Windows Explorer opens that application instead of your.
If you want to be able to double click your file in Windows Explorer and open your app, you need to change the file name extension you are using AND create the proper association for that extension.
The file extension associations are defined by entries in the registry. You can create these per-machine (in HKLM\Software\Classes) or per-user (in HKCU\Software\Classes), though per-machine is the most common case. For more details about the actual registry entries and links to MSDN documentation and samples, check my answer to this SO question on Vista document icon associations.
I think it's a matter of create the right registry values,
or check this codeproject's article
You can save file with whatever extension you want, just put it in file name when saving file.
I sense that your problem is "How I can save file in something other than RTF?". You'll have to invent your own format, but you actually do not want that. You still can save RTF into file named mynote.not.
I would advise you to keep using format which is readable from other programs. Your users will be thankful once they want to do something with their notes which is not supported by your program.

Categories