What would be the return type of the following method? (T)
public T GetDirectoryContentsRecursively (string path) { ... }
The method will read the contents of a remote directory, and read the contents of each sub-directory and each of that object's sub-directories and so on.
I have thought about using List<object>, where object could be another List<object> etc... but I don't want the caller to have to be casting everything into FileSystemInfos every time they want to use the method.
Every file must be a FileInfo and every directory a DirectoryInfo, both of which inherit the abstract class FileSystemInfo.
I just can't figure out what data type is best used to represent this.
Any ideas? Do I need to make my own DirectoryTree type?
Edit: The data is to be fetched from a server, probably directory by directory, one at a time. What I need to do is take this data and reconstruct it into something that I can pass to the user. This means I can't just pass a DirectoryInfo, then call its GetFileSystemInfos() because the Directory will not exist on the local machine.
I think maybe the approach is wrong, what are you trying to achieve with a tree structure that you can't by using the APIs directory as and when you need to?
If the intention is to just walk the folder/file structure on the remote directory then you don't necessary need to build your own in-memory representation to do this. If you are rendering the structure, just grab the top level, and load other levels on demand.
If you really want to go down this route then you could just return IEnumerable<string> with all the directory and file paths. DirectoryInfo and FileInfo are relatively expensive objects. It all depends on purpose, can you give any more info?
see below information of SortedSet if you are uisng .net 4.0
http://msdn.microsoft.com/en-us/library/dd412070.aspx
and Directory.Enumarate in .net 4.0 is desinged for the task you are doing.
Try something like this:
class MySweetObject{
HashSet fileInfoSet;
HashSet directoryInfoSet;
//Logic needed to manipulate files as you see fit
//Logic needed to access files as you see fit
}
Then write it as:
public MySweetObject GetDirectoryContentsRecursively (string path) { ... }
Create a custom object and pass that around to the caller.
Related
I would like to determine which source file defines a specific type using Mono.Cecil.
For methods, I can use the SequencePoint collection (for example, I could grab the first SequencePoint and fetch the Url of it's Document). I'm assuming this would always work as long as the PDBs are loaded since even empty methods should have at least one instruction (nop):
if (methodDefinition.DebugInformation.HasSequencePoints) {
var firstSequencePoint = methodDefinition.DebugInformation.SequencePoints[0];
return firstSequencePoint.Document.Url;
}
However, for types, I am not sure how this would work. Do the PDB files even contain the mapping between a type and a document? Obviously a type can be defined across multiple documents (in case of partial classes, for instance) which is fine - but is this information actually available? If yes, is it exposed in Mono.Cecil? Mono.Cecil.Cil.PortablePdbReader does read CustomDebugInformation for a module but I don't think this is it (I looked at the raw data and it doesn't contain anything of interest).
The attribute [CallerFilePath] seems to do what I need to do:
How to find path to .cs file by its type in C#
...but I would like to be able to avoid having to add this new prop to every type that I want to check:
public string SourceFilePath { get; } = Helper.GetCallerFilePath();
What I have tried:
Adding this method at runtime does not seem to be an option.
Using it in a base class does not seem to work either (it returns the
path of the base class).
My guess is that this is somehow feasible, because an exception is able to give you this kind of info (from any given type).
What I really want to do in my particular case is: I have a set of cs files that can be identified via their implemented interface, and I want to know their location in the file structure of the project.
So in this case I don't need to know the file location of any given type, but it would be my preferred approach if that's possible.
I'm trying to emulate my custom project file as new PS Drive. I am trying to create my custom Powershell Provider that is derived from NavigationCmdletProvider. I have overridden PSDriveInfo to read and contain the project from the file and filepath is in the root of PSDriveInfo.
I can't override GetItem properly. What I want to do is use GetNamesFromPath(path, out tableName, out rowNumber) method. Since my custom project is basically dataset, I would like to use tableName to get the DataTable and rowNumber for ID of DataRow.
The problem is that I get the "path doesn't exist" kind of error. It doesn't event get into the overridden method. Am I missing something to override? The filepath doesn't exist really, but I simply need to handle the path and use WriteItemObject with what I want as object(s) returned, without checking is it valid path.
Edit 1:
One thing I noticed is that it never gets into GetItem and therefore into IsValidPath. When I debug and use breakpoints, first I load the drive and then Set-Location to the drive, IsItemContainer is called (it has to be overridden for Set-Location to work).
GetItem and IsValidPath are not called at all, as if it checks for valid path before calling overridden method. Can NavigationCmdletProvider work with non-existing paths (except for the file itself), just work with strings that will manually be handled as paths would?
Make sure you override the IsValidPath and ItemExists methods:
protected override bool IsValidPath(string path)
{
return true;
}
protected override bool ItemExists(string path)
{
return true;
}
If you are extending NavigationCmdletProvider then you should override IsValidPath, ItemExists, GetItem, GetChildItems and possibly other methods depending on what features you want to support for your PS drives.
The best way to find out which methods are missing implementation is to override all the virtual methods and put a breakpoint in each one. Then execute a cmdlet and see in the debugger what gets called and what are the parameter values.
Unfortunately, there isn't a lot of detailed documentation about implementing custom PowerShell providers. However, you can find a quite detailed tutorial on MSDN about this topic with a lot of source code examples. Additionally, you can take a look at the PowerShell VFS project - it's a wrapper around PowerShell provider API to make it easier to build complicated providers.
I am implementing an application and I have a few lists with some stuff in it, which is always the same, but I don't want to implement this in my real logic stuff.
Is there any way to save these items in your application? I've read some things about saving these items in a settingsfile.
Is this the best way, or there are better ways? and how can I do this?
You can save it in the application settings file
Save in XML. You can bind directly to xml in wpf. See: http://joshsmithonwpf.wordpress.com/2007/06/04/binding-to-xml/
If the content of the list is supposed to never be changed you can make them private static fields in a static class the provides a mthod to create a new instance of the list.
If the content of the list is supposed to be changed, it is a good idea to store it in the application settings file.
If the content of the list is supposed to be changed per user you should save it in the user settings file.
Depending of the content itself, I like to load the content of list into a database table. For example, a list of school would be stored in a table calle T_Ref_Schools. The Ref indicated to me that those values can be changed over time but not often.
I've got the hierarchial structure of files and folders inside of my application. Application works with absolute paths, which are stored in FileNode.Items list of strings.
When i've got to save my project, I serialize FileNode class in XML. But, I need to convert absolute paths to relatives (if possible) and then serialize.
So, my question is: Is there any solution to do it on the fly (i.e. any flag near the property which does any action with it) or i need to manually convert paths before every serialization and after every deserializaion?
Thank's a lot for your answers
You could make a separate property on your FileNode class which returns relative paths, and add the [XmlIgnore] attribute to the original property to prevent it from being serialized.
Alternatively, you could implement IXmlSerializable to control the serialization yourself.
No, there's no automatic way to do that.
You can implement ISerializable or get your XML serialized object and make your paths relative through XmlDocument