I am getting list of startup applications, and wants to get only Path of application running at startup. The list of startup application also contain the parameter passed to the application, which are in different pattern; examples are
C:\Program Files (x86)\Internet Download Manager\IDMan.exe /onboot
"C:\Program Files\Process Hacker 2\ProcessHacker.exe" -hide
"C:\Program Files\CCleaner\CCleaner64.exe" /MONITOR
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --no-startup-window /prefetch:5
"C:\Program Files (x86)\GlassWire\glasswire.exe" -hide
C:\Program Files\IDT\WDM\sttray64.exe
I am trying to use following regex
Regex.Matches(input, "([a-zA-Z]*:[\\[a-zA-Z0-9 .]*]*)");
Kindly guide me how can I extract only application path ignoring all the parameters and other startup commands.
Try this simple approach:
string cmd = "\"C:\\Program Files (x86)\\GlassWire\\glasswire.exe\" -hide";
int index = cmd.ToLower().LastIndexOf(".exe");
string path = cmd.Substring(0, index+4);
index = path.IndexOf("\"");
if (index >= 0)
path = path.Substring(index + 1);
Since the expected input list will contains list of executable files, all are having the .exe extension, we can make use of that extension here By suing .Substring() method of String class. Sample usage will be like this:
List<string> inputMessageStr = PopulateList(); // method that returns list of strings
List<string> listofExePaths= inputMessageStr.Select(x=> x.Substring(0, x.IndexOf(".exe") + 4)).ToList();
There are many cases which can break the normal method of finding the complete executable path form a given string.
Simply finding ".exe" won't work in general case. Atleast one space will separate the actual complete executable path from the parameters.
Note: This solution is based on assumption that the executable would be present on its intended path. Since, OP is having a list of paths of application running at startup this assumption holds.
public string GetPathOnly(string strSource)
{
//removing all the '"' double quote characters
strSource.Trim( new Char[] {'"'} );
int i;
string strExecutablePath = "";
for(i = 0; i < strSource.Length; ++i)
{
if(strSource[i] == ' ')
{
if(File.Exists(strExecutablePath))
{
return strExecutablePath;
}
}
strExecutablePath.Insert(strExecutablePath.Length, strSource[i]);
}
if(File.Exists(strExecutablePath))
{
return strExecutablePath;
}
return ""; // no actual executable path found.
}
Related
I just need a specific answer here:
I am able to create a file containing the command and options I need in the specific format required on each line for example :
#"C:\mydosprog\mydosprog.exe" -o=option1 -option2
#"C:\mydosprog\mydosprog.exe" -o=option1 -option2
#"C:\mydosprog\mydosprog.exe" -o=option1 -option2
... and more lines
Here is the code I am using :
var launchmyfile = File.ReadAllLines(#"c:\foo\mycommands.txt");
for (int i = 0; i < inputLines.Length; i++)
System.Diagnostics.Process.Start(???????);
//this is where i'm battling and at the ??'s :-)
Is there a simple and efficient way of doing this ? (Similar to a dos batch file but in c#)
If so how ?
I would appreciate any tips and tricks and answers
Thank you
You iterate inputLines instead of launchmyfile.
However you need to:
Remove the # symbol from the file, its meaningless as as the verbatim decorator when its inside a string and not valid in a path for Process.Start
Keep the quotes, these can be used to distinguish the path from the command line & you will need to break them apart in your program
// test file
File.WriteAllLines(#"C:\TEMP\TEST.TXT", new string[] {
#"""c:\windows\system32\ping.exe"" -n 3 google.com",
#"""c:\windows\system32\ping.exe"" -n 3 google.com",
#"""c:\windows\system32\ping.exe"" -n 3 google.com",
});
var launchmyfile = File.ReadAllLines(#"C:\TEMP\TEST.TXT");
for (int i = 0; i < launchmyfile.Length; i++)
{
// 2nd " breaks the path from the command line
int commandLinePos = launchmyfile[i].IndexOf("\"", 1);
// get path
string executable = launchmyfile[i].Substring(1, commandLinePos - 1);
// get command line
string commandLine = launchmyfile[i].Substring(commandLinePos + 2);
// execute
System.Diagnostics.Process.Start(executable, commandLine);
}
I'm trying to write a nifty content loader in XNA to avoid having to individually load each asset. However, I'm having trouble describing directory locations because the default directory for File operations is the location of the exe, but XNA's Content.Load uses a default directory of the Content folder.
foreach (string subD in Directory.GetDirectories("..\\..\\..\\..\\Happy WorkerContent\\gfx\\", "*.*", SearchOption.AllDirectories))
{
foreach (string s in Directory.GetFiles(subD))
{
string file = Path.GetFileNameWithoutExtension(s);
if (Enum.IsDefined(typeof(Tex), file))
{
Console.WriteLine(subD);
Console.WriteLine(file);
GXDict.Add(Path.GetFileNameWithoutExtension(s), GV.C_Game1.Content.Load<Texture2D>(subD + "\\" + file));
}
}
}
My error is because subD is, for example, "........\Happy WorkerContent\gfx\level entities\terrains", but Content.Load expects "gfx\level entities\terrains".
I could do something like subD.Substring(32), but this seems messy, especially if I rename any folders or anything later (and may not work in the published version?). Is there a good way to say "I only want the part of the file which is after the "Happy WorkerContent" directory?
You could write a method to return the text following a particular target string.
Then if you needed to search for a different string, you'd just need to pass a different target string to the method.
For example:
// Returns the contents of text following the target string,
// or "" if the target string wasn't found.
public static string ContentAfter(string text, string target)
{
int index = text.IndexOf(target);
if (index >= 0)
return text.Substring(index + target.Length);
else
return "";
}
Then you'd call it like:
string test = "..\\..\\..\\..\\Happy WorkerContent\\gfx\\whatever";
string target = "\\Happy WorkerContent\\";
string following = ContentAfter(test, target);
That wouldn't work so great if you had two strings matching the target string in the text. The method would return all the text after the first match, which would include the second target string of course.
How do you get the last folder/directory out of user-input regardless of if the input is a path to a folder or a file? This is when the folder/file in question may not exist.
C:\Users\Public\Desktop\workspace\page0320.xml
C:\Users\Public\Desktop\workspace
I'm trying to get out the folder "workspace" out of both examples, even if the folder "workspace" or file "page0320.xml" doesn't exist.
EDIT: Using BrokenGlass's suggestion, I got it to work.
String path = #"C:\Users\Public\Desktop\workspace";
String path2 = #"C:\Users\Public\Desktop\workspace\";
String path3 = #"C:\Users\Public\Desktop\workspace\page0320.xml";
String fileName = path.Split(new char[] { '\\' }).Last<String>().Split(new char[] { '/' }).Last<String>();
if (fileName.Contains(".") == false)
{
path += #"\";
}
path = Path.GetDirectoryName(path);
You can substitute any of the path variables and the output will be:
C:\Users\Public\Desktop\workspace
Of course, this is working under the assuption that files have extensions. Fortunately, that assumption works for my purposes.
Thanks all. Been a long-time lurker and first-time poster. It was really impressive how fast and helpful the responses were :D
use Path.GetDirectoryName :
string path = Path.GetDirectoryName(#"C:\Users\Public\Desktop\workspace\page0320.xml");
string path2 = Path.GetDirectoryName(#"C:\Users\Public\Desktop\workspace\");
Note the trailing backslash in the path though in the second example - otherwise workspace will be interpreted as file name.
I will use DirectoryInfo in this way:
DirectoryInfo dif = new DirectoryInfo(path);
if(dif.Exist == true)
// Now we have a true directory because DirectoryInfo can't be fooled by
// existing file names.
else
// Now we have a file or directory that doesn't exist.
// But what we do with this info? The user input could be anything
// and we cannot assume that is a file or a directory.
// (page0320.xml could be also the name of a directory)
You can use GetFileName after GetDiretoryName from the Path class in the System.IO namespace.
GetDiretoryName will get the path without the filename (C:\Users\Public\Desktop\workspace).
GetFileName then returns the last part of the path as if it is a extensionless file (workspace).
Path.GetFileName(Path.GetDirectoryName(path));
EDIT: the path must have a trailing path separator to make this example work.
If you can make some assumptions then its pretty easy..
Assumption 1: All files will have an extension
Assumption 2: The containing directory will never have an extension
If Not String.IsNullOrEmpty(Path.GetExtension(thePath))
Return Path.GetDirectoryName(thePath)
Else
Return Path.GetFileName(thePath)
End If
Like said before, there's not really a feasible solution but this might also do the trick:
private string GetLastFolder(string path)
{
//split the path into pieces by the \ character
var parts = path.Split(new[] { Path.DirectorySeparatorChar, });
//if the last part has an extension (is a file) return the one before the last
if(Path.HasExtension(path))
return parts[parts.Length - 2];
//if the path has a trailing \ return the one before the last
if(parts.Last() == "")
return parts[parts.Length - 2];
//if none of the above apply, return the last element
return parts.Last();
}
This might not be the cleanest solution but it will work. Hope this helps!
Is there an easy way to get a list of filenames that matach a filename pattern including references to parent directory? What I want is for "..\ThirdParty\dlls\*.dll" to return a collection like ["..\ThirdParty\dlls\one.dll", "..\ThirdParty\dlls\two.dll", ...]
I can find several questions relating matching files names including full path, wildcards, but nothing that includes "..\" in the pattern. Directory.GetFiles explicitly disallows it.
What I want to do with the names is to include them in a zip archive, so if there is a zip library that can understand relative paths like this I am happier to use that.
The pattern(s) are coming from an input file, they are not known at compile time. They can get quite complex, e.g ..\src\..\ThirdParty\win32\*.dll so parsing is probably not feasible.
Having to put it in zip is also the reason I am not very keen on converting the pattern to fullpath, I do want the relative paths in zip.
EDIT: What I am looking for really is a C# equivalent of /bin/ls.
static string[] FindFiles(string path)
{
string directory = Path.GetDirectoryName(path); // seperate directory i.e. ..\ThirdParty\dlls
string filePattern = Path.GetFileName(path); // seperate file pattern i.e. *.dll
// if path only contains pattern then use current directory
if (String.IsNullOrEmpty(directory))
directory = Directory.GetCurrentDirectory();
//uncomment the following line if you need absolute paths
//directory = Path.GetFullPath(directory);
if (!Directory.Exists(directory))
return new string[0];
var files = Directory.GetFiles(directory, filePattern);
return files;
}
There is the Path.GetFullPath() function that will convert from relative to absolute. You could use it on the path part.
string pattern = #"..\src\..\ThirdParty\win32\*.dll";
string relativeDir = Path.GetDirectoryName(pattern);
string absoluteDir = Path.GetFullPath(relativeDir);
string filePattern = Path.GetFileName(pattern);
foreach (string file in Directory.GetFiles(absoluteDir, filePattern))
{
}
If I understand you correctly you could use Directory.EnumerateFiles in combination with a regular expression like this (I haven't tested it though):
var matcher = new Regex(#"^\.\.\\ThirdParty\\dlls\\[^\\]+.dll$");
foreach (var file in Directory.EnumerateFiles("..", "*.dll", SearchOption.AllDirectories)
{
if (matcher.IsMatch(file))
yield return file;
}
I have a directory that contains jpg,tif,pdf,doc and xls. The client DB conly contains the file names without extension. My app has to pick up the file and upload the file. One of the properties of the upload object is the file extension.
Is there a way of getting file extension if all i have is the path and name
eg:
C:\temp\somepicture.jpg is the file and the information i have through db is
c:\temp\somepicture
Use Directory.GetFiles(fileName + ".*"). If it returns just one file, then you find the file you need. If it returns more than one, you have to choose which to upload.
Something like this maybe:
DirectoryInfo D = new DirectoryInfo(path);
foreach (FileInfo fi in D.GetFiles())
{
if (Path.GetFileNameWithoutExtension(fi.FullName) == whatever)
// do something
}
You could obtain a list of all of the files with that name, regardless of extension:
public string[] GetFileExtensions(string path)
{
System.IO.DirectoryInfo directory =
new System.IO.DirectoryInfo(System.IO.Path.GetDirectoryName(path));
return directory.GetFiles(
System.IO.Path.GetFileNameWithoutExtension(path) + ".*")
.Select(f => f.Extension).ToArray();
}
Obviously, if you have no other information and there are 2 files with the same name and different extensions, you can't do anything (e.g. there is somepicture.jpg and somepicture.png at the same time).
On the other hand, usually that won't be the case so you can simply use a search pattern (e.g. somepicture.*) to find the one and only (if you're lucky) file.
Search for files named somepicture.* in that folder, and upload any that matches ?
Get the lowest level folder for each path. For your example, you would have:
'c:\temp\'
Then find any files that start with your filename in that folder, in this case:
'somepicture'
Finally, grab the extension off the matching filename. If you have duplicates, you would have to handle that in a unique way.
You would have to use System.IO.Directory.GetFiles() and iterate through all the filenames. You will run into issues when you have a collision like somefile.jpg and somefile.tif.
Sounds like you have bigger issues than just this and you may want to make an argument to store the file extension in your database as well to remove the ambiguity.
you could do something like this perhaps....
DirectoryInfo di = new DirectoryInfo("c:/temp/");
FileInfo[] rgFiles = di.GetFiles("somepicture.*");
foreach (FileInfo fi in rgFiles)
{
if(fi.Name.Contains("."))
{
string name = fi.Name.Split('.')[0].ToString();
string ext = fi.Name.Split('.')[1].ToString();
System.Console.WriteLine("Extension is: " + ext);
}
}
One more, with the assumption of no files with same name but different extension.
string[] files = Directory.GetFiles(#"c:\temp", #"testasdadsadsas.*");
if (files.Length >= 1)
{
string fullFilenameAndPath = files[0];
Console.WriteLine(fullFilenameAndPath);
}
From the crippled file path you can get the directory path and the file name:
string path = Path.GetDirectoryName(filename);
string name = Path.GetFileName(filename);
Then you can get all files that matches the file name with any extension:
FileInfo[] found = new DirectoryInfo(path).GetFiles(name + ".*");
If the array contains one item, you have your match. If there is more than one item, you have to decide which one to use, or what to do with them.
All the pieces are here in the existing answers, but just trying to unify them into one answer for you - given the "guaranteed unique" declaration you're working with, you can toss in a FirstOrDefault since you don't need to worry about choosing among multiple potential matches.
static void Main(string[] args)
{
var match = FindMatch(args[0]);
Console.WriteLine("Best match for {0} is {1}", args[0], match ?? "[None found]");
}
private static string FindMatch(string pathAndFilename)
{
return FindMatch(Path.GetDirectoryName(pathAndFilename), Path.GetFileNameWithoutExtension(pathAndFilename));
}
private static string FindMatch(string path, string filename)
{
return Directory.GetFiles(path, filename + ".*").FirstOrDefault();
}
Output:
> ConsoleApplication10 c:\temp\bogus
Best match for c:\temp\bogus is [None found]
> ConsoleApplication10 c:\temp\7z465
Best match for c:\temp\7z465 is c:\temp\7z465.msi
> ConsoleApplication10 c:\temp\boot
Best match for c:\temp\boot is c:\temp\boot.wim