I write a file called "Blaitière.bytes" in C# on OSX. Then I list all files using Directory.GetFiles, I get "Blaitie`re.bytes" instead. Is there a way to convert from one to another? i.e. is there a method for me to know to what my filename will be converted to?
This answer (https://stackoverflow.com/a/6153713/217022) explains why it happens - file names on OSX have to be in fully decomposed unicode, so
calling:
string path = ...my path...
path = path.Normalize(System.Text.NormalizationForm.FormKD);
solves the problem.
Related
I am writing a utility that edits .docx files. I've made it so that when the user right clicks on the correct type of file, it automatically makes the changes and saves the document with a bit of text appended to the file name. All of this works great, except for the fact that I am receiving heavily truncated file names. If the file name contains more than one word, the string passed to the program is has most of its characters replaced by a single ~. Is there any way to either read the original file name, or have the parameter be the full string?
I found the solution to what I was trying to do. I ended up using the C# method Path.GetFullPath.
string path = Path.GetFullPath(originalpath);
This outputs the full file name as opposed to the truncated one.
http://msdn.microsoft.com/en-us/library/system.io.path.getfullpath.aspx
File.getCanonicalPath will give you what you want
http://msdn.microsoft.com/en-us/library/aa988183(v=vs.80).aspx
Put the whole path between two double quot; like:
var fn = "\"C:\\Path With Spaces And Special Characters\\#\\to\\My File.docx\"";
// send fn as an argument to the other process
I am attempting to retrieve jpeg and jpg files using the following statement:
string[] files = Directory.GetFiles(someDirectoryPath, "*.jp?g");
MSDN's docs for System.IO.Directory.GetFiles(string, string) state that ? represents "Exactly zero or one character.", however the above block selects jpeg files but omits jpg files.
I am currently using the overly-permissive search pattern "*.jp*g" to achieve my results, but it wrinkles my brain because it should work.
From the docs you linked to:
A searchPattern with a file extension of one, two, or more than three characters returns only files having extensions of exactly that length that match the file extension specified in the searchPattern.
I suspect that's the problem. To be honest, I'd probably fetch all the files and then postprocess them in code - it'll make for code which is simpler to reason about than relying on the Windows path-handling oddities.
You could either use "*" as a pattern and process the result yourself OR use
string[] files = Directory.GetFiles(someDirectoryPath, "*.jpg").Union (Directory.GetFiles(someDirectoryPath, "*.jpeg")).ToArray();
According to the Docs the pattern you use would return only files with extensions which are 4 characters long.
MSDN reference on Union
How can I automate searching for strings in all .cs files and add certain code for localization, where I can use a key in resource files. Let's say there is a
string s = "A"
in cs files. I need to change it to something like,
string s = ("A","ResourceFileKey")
and then add to the resource file keys with country specific values. Is there any tool available? Presently, I am using macros and searching ...
If you just want to get all string literals out of your C# code to put them into your resource file, I suggest not to parse your C# code, but the IL code generated by the C# compiler, that ist much (!) easier.
Here is a helpful link with some code showing how to parse IL code:
http://www.codeproject.com/KB/cs/sdilreader.aspx
That, of course, does not solve your problem how to modify your existing code.
You can write your own. Its a simple String.Replace call.
Read your file using FileStream Execute ReadToEnd method and you'll get a string. Then use String.Replace on it which will again return you a modified string. Replace your file content with the new string and save.
The directory 'C:\temp' has two files named 'GZ96A7005.tif' and 'GZ96A7005001.tif'. They have different length with the same extension. Now I run below code:
string[] resultFileNames = Directory.GetFiles(#"C:\temp", "????????????.tif");
The 'resultFileNames' return two items 'c:\temp\GZ96A7005.tif' and 'c:\temp\GZ96A7005001.tif'.
But the Window Search will work fine. This is why and how do I get I want?
For Directory.GetFiles, ? signifies "Exactly zero or one character." On the other hand, you could use DirectoryInfo.GetFiles, for which ? signifies "Exactly one character" (apparently what you want).
EDIT:
Full code:
string[] resultFileNames = (from fileInfo in new DirectoryInfo(#"C:\temp").GetFiles("????????????.tif") select fileInfo.Name).ToArray();
You can probably skip the ToArray and just let resultFileNames be an IEnumerable<string>.
People are reporting this doesn't work for them on MS .NET. The below exact code works for me with on Mono on Ubuntu Hardy. I agree it doesn't really make sense to have two related classes use different conventions. However, that is what the documentation (linked above) says, and Mono complies with the docs. If Microsoft's implementation doesn't, they have a bug:
using System;
using System.IO;
using System.Linq;
public class GetFiles
{
public static void Main()
{
string[] resultFileNames = (from fileInfo in new DirectoryInfo(#".").GetFiles("????????????.tif") select fileInfo.Name).ToArray();
foreach(string fileName in resultFileNames)
{
Console.WriteLine(fileName);
}
}
}
I know I've read about this somewhere before, but the best I could find right now was this reference to it in Raymond Chen's blog post. The point is that Windows keeps a short (8.3) filename for every file with a long filename, for backward compatibility, and filename wildcards are matched against both the long and short filenames. You can see these short filenames by opening a command prompt and running "dir /x". Normally, getting a list of files which match ????????.tif (8) returns a list of file with 8 or less characters in their filename and a .tif extension. But every file with a long filename also has a short filename with 8.3 characters, so they all match this filter.
In your case both GZ96A7005.tif and GZ96A7005001.tif are long filenames, so they both have a 8.3 short filename which matches ????????.tif (anything with 8 or more ?'s).
UPDATE... from MSDN:
Because this method checks against
file names with both the 8.3 file name
format and the long file name format,
a search pattern similar to "*1*.txt"
may return unexpected file names. For
example, using a search pattern of
"*1*.txt" returns "longfilename.txt"
because the equivalent 8.3 file name
format is "LONGFI~1.TXT".
UPDATE: The MSDN docs specifiy different behavior for the "?" wildcard in Directory.GetFiles() and DirectoryInfo.GetFiles(). The documentation seems to be wrong, however. See Matthew Flaschen's answer.
The ? character matches "zero or one" characters... so from what you have I would imagine that your search pattern will match any file ending in ".tif" that is between zero and twelve characters long.
Try dropping another file in that is only three characters long with a ".tif" extension and see if the code picks that up as well. I have a sneaking suspicion that it will ;)
As far as the Windows search is concerned, it is most definately not using the same algorithm under the hood. The ? character might have a very different meaning there than it does in the .Net search pattern specification for the Directory.GetFiles(string, string) method.
string path = "C:/";
var files = Directory.GetFiles(path)
.Where(f => f.Replace(path, "").Length == 8);
A little costly with the string replacement. You can add whatever extension you need.
I want to get title of shortcut, not file name, not description, but title.
how to get it?
I have learn to resolve its target path from here, How to resolve a .lnk in c#
but i don't find any method to get its title.
(source: ggpht.com)
(source: ggpht.com)
It sounds like you might be trying to get the title of the file the link points to, as JRL suggests.
If you're not trying to do that, I'd recommend opening up one of these .lnk files in a hex editor like XVI32. You can probably tell from there whether the Chinese name displayed is embedded in the .lnk file or is somewhere else.
If it's somewhere else, it may be an Extended File Property. There's some source code that may help with retrieving that info: Extended File Properties
If by some chance it is inside the .lnk file, I recommend looking at the Windows Shortcut Specification to get offset information and such on the location of that data.
There is a Desktop.ini hidden file in shortcuts directory, the Desktop.ini file records display strings info of shortcuts.
Desktop.ini file sample:
[LocalizedFileNames]
Windows Update.lnk=#%SystemRoot%\system32\wucltux.dll,-1
Default Programs.lnk=#%SystemRoot%\system32\sud.dll,-1
You can use the property system APIs in latest relase of Code pack:
(all the 670+ properties in the system are accesible using simple property accessors)
http://code.msdn.microsoft.com/WindowsAPICodePack
I know your current need is only limited title of lnk files. Using the above library, the sample code might look like:
ShellLink myLink = ShellObject.FromParsingName("c:\somepath\myLink.lnk");
string title = myLink.Properties.System.Title.Value;
// This is what its pointing to...
string target = myLink.Properties.System.TargetParsingPath.Value;
Please define "title". The only attributes that sound relevent are the shortcut's file name, the target's file name, and the .lnk file's description data.
Assuming you mean the title of the file the link points to, not the link itself, and that you are talking about Windows, then it's done via a feature in NTFS, alternative streams. You can access those streams using code in this article.
Looking around on creating shortcuts, looks like there's a lot of jumping through hoops with scripting objects. But am I missing something? If you have a path to the shortcut, the name should be exactly what you find in the path, not some attribute you have to look up.
Dim f As FileInfo = New FileInfo("C:\Name of shortcut.lnk")
Dim title As String = f.Name.Replace(".lnk", String.Empty)