OdinSearch is a tool written in C# that lets users search thru local file systems for matches and do something based on said matches. The class library has an expandable architecture in which developers can subclass a ‘communcations’ class and pass it to the searcher class to feed matching results to it. Included in the class library to serve both as examples and starting points for custom communication classes are examples ranging from feeding results to a file, saving results to an Excel comma separated value file, creating symbolic links based on matching and executing shell commands on matches. The current end user facing aspect of this project – FileInventoryConsole is built to show off some of the flexibility class design including loading extern DLLs in a plugin fashion for this project.
This is the main branch for my project. It’s currently based off of the recent Windows release for the console front end located here. If and when version two comes out, the branch main is based on will change.
using System;
using OdinSearchEngine;
using OdinSearchEngine.OdinSearch_OutputConsumerTools;
using System.IO;
static class Program
{
static void Main(string[] args)
{
// This sets the search to match to file with these possible extentions
// This class is how to specify what to search for
SearchTarget TargetCompiledWindowsExtension = new SearchTarget();
TargetCompiledWindowsExtension.FileName.Add("*.exe");
TargetCompiledWindowsExtension.FileName.Add("*.dll");
TargetCompiledWindowsExtension.FileNameMatching = SearchTarget.MatchStyleString.MatchAny;
// The default Contructor automatically adds all local drives that repeart 'ready'
SearchAnchor AllLocalReadyDrives = new SearchAnchor();
// One has to manually turn on looking in the subfolders.
AllLocalReadyDrives.EnumSubFolders = true;
// This example 'AnotherExample' shows another way to specify starting points.
// This just shows it. It's not used in this example code otherwise.
SearchAnchor AnotherExample = new SearchAnchor("C:\\ThisSpecificFolder");
AnotherExample.AddAnchor("D:\\AndSearchThisFolderToo");
AnotherExample.EnumSubFolders = true;
// OdinSearch is the search class. Don't forget to add your
// SearchTargets and SearchAnchors to the lists in it.
OdinSearch SearchMan = new OdinSearch();
SearchMan.AddSearchAnchor(AllLocalReadyDrives);
SearchMan.AddSearchTarget(TargetCompiledWindowsExtension);
// the OdinSearch Class requires passing a communication class subclassed
// from OdinSearch_OutputConsumerBase. this particular one just stores the
// results in a list for later use.
OdinSearch_OutputConsumerGatherResults GetResults = new OdinSearch_OutputConsumerGatherResults();
// Starts the search.
SearchMan.Search(GetResults);
// You may possibly need to have this call before waiting pending threads. I’ve had exceptions sometimes if it’s not there, but if you aren’t getting any, this call to Thread.Sleep() is unneeded.
Thread.Sleep(200); // Just a 1/5 sec to let things spin up.
while (true)
{
// The searcher spawns threads and this routine pausing your code running until they're done.
SearchMan.WorkerThreadJoin();
break;
}
// this example just writes the results to the console screen.
// OdinSearch_OutputSimpleConsole is a communication class that that does that too.
Console.WriteLine("There were " + GetResults.Results.Count.ToString() + " result(s) that matched");
foreach (FileSystemInfo s in GetResults.Results)
{
Console.WriteLine(s.FullName);
}
Console.WriteLine("End of Results");
}
}
This class can write to the console or a file stream. There are a few settings to adjust for control such as flushing the stream after each write, outputs a friendly string or strictly the match’s location. Note the one the front end uses a class similar to this – called OdinSearch_OutputConsole
This class writes the match’s info (such as, file name, location, attributes and the rest) out to a comma separated value text file (for Excel) to open up later. There are options to customize what to put in the list; however, default is all possible items. The console front end users one called OdinSearchOutputCVSWriter.
This class introduces a way to filter matches based on a routine beyond the file searching to help control matching. There’s also an example of what do to – check if an executable file has a trusted certificate or not. The example has a possibility to control if the list it makes of those that are trusted vs those that are not trusted. OdinSearchOutputConsumer_FilterCheck_CertExample
This class is not directly accessible by users of the front end, you’ll need to clone the project and build it to get use. It will create symbolic links in a target location (and sub folder) based on file extensions. For example, assuming target is C:\SearchResults. All matching files with a .PDF extension would get a placed in the target location at C:\SearchResults\PDF. The class also has a way in place to customize how it creates symbolic links and folders too.
When beginning a search (OdinSearch.Search()), search folder in the SearchAnchors in list of SearchAnchors will get its own search thread to search. For example, passing 4 instances of SearchAnchors with total 20 different roots ‘starting points’ will get 20 threads searching. The threads are synched with the lock keyword on any call into your communication class.
When the search is about the begin, a call to the communication class routine SearchBegin() occurs. Here is the last stop before the search begins. Here you can initialize your stuff to manage processing matches. Thrown an exception if you can’t initialize ok. There’s code also setup to trigger a call to the communication class AllDone() routine once all threads are finished processing. Of VITAL IMPORTANCE is that while a thread is calling into your communication class, it can’t continue processing items until you return control to it. If you need to do something computationally expensive, it’s recommended to put the FileSystemItem into a buffer of some sort – hence the example class above, [OdinSearch_OutputConsumer_FilterCheck]() That class introduces a way to make a list of possible matches and discard the possible matches that don’t. If circumstances allow me to add container handling (i.e. zip files) transparently, this may change.
For plugin writers, your managed plugin gets an instance of its class created and OdinSearch uses a wrapper class to commicate with it. For umananged plugins, we use a similar plan i.e. a wrapper class that lets OdinSearch treat it as if a c# class effectively.
License is currently MIT version that comes with the download named LICENSE.txt.
I welcome feedback and feature suggestions/ideas/bug reports. Thanks for reading.