Changing a programs process name in task manager? - c#

Okay so I've been looking around and I can't find an answer anywhere.
What I want my program to do is every time I run it, the name that shows up in the task manager is randomized.
There is a program called 'Liberation' that when you run it, it will change the process name to some random characters like AeB4B3wf52.tmp or something. I'm not sure what it is coded in though, so that might be the issue.
Is this possible in C#?
Edit:
I made a sloppy work around, I created a separate program that will check if there is a file named 'pb.dat', it will copy it to the temp folder, rename it to a 'randomchars.tmp' and run it.
Code if anyone was interested:
private void Form1_Load(object sender, EventArgs e)
{
try
{
if (!Directory.Exists(Environment.CurrentDirectory + #"\temp")) // Create a temp directory.
Directory.CreateDirectory(Environment.CurrentDirectory + #"\temp");
DirectoryInfo di = new DirectoryInfo(Environment.CurrentDirectory + #"\temp");
foreach (FileInfo f in di.GetFiles()) // Cleaning old .tmp files
{
if (f.Name.EndsWith(".tmp"))
f.Delete();
}
string charList = "abcdefghijklmnopqrstuvwxyz1234567890";
char[] trueList = charList.ToCharArray();
string newProcName = "";
for (int i = 0; i < 8; i++) // Build the random name
newProcName += trueList[r.Next(0, charList.Length)];
newProcName += ".tmp";
if (File.Exists(Environment.CurrentDirectory + #"\pb.dat")) // Just renaming and running.
{
File.Copy(Environment.CurrentDirectory + #"\pb.dat", Environment.CurrentDirectory + #"\temp\" + newProcName);
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = Environment.CurrentDirectory + #"\temp\" + newProcName;
p.UseShellExecute = false;
Process.Start(p);
}
}
catch (Exception ex)
{
MessageBox.Show("I caught an exception! This is a bad thing...\n\n" + ex.ToString(), "Exception caught!");
}
Environment.Exit(-1); // Close this program anyway.
}

The process name in the task manager bases on the executable name without the extension, which you can not change while it is running.
Read the documentation:
The ProcessName property holds an executable file name, such as
Outlook, that does not include the .exe extension or the path. It is
helpful for getting and manipulating all the processes that are
associated with the same executable file.

in visual studio go to Project - Properties - Application - Assembly information and change Title

I would implement a host application to do this that simply runs and monitors a sub process (other executable). You may rename a file as such:
System.IO.File.Move("oldfilename", "newfilename");
and start the process like this:
Process.Start("newfilename");
This would mean that instead of one process you would have two, but the owner process only needs to be alive under startup - in order to change the name.

Related

Environment.CurrentDirectory returns odd results

I have some issues with Environment.CurrentDirectory, it sometimes goes to the System32 folder. I looked online and found out why this happens and what alternatives I have (like Application.StartupPath and stuff like that) but the problem is the code is in a .dll that I am using and I can't edit it (or can I).
Is there anything I can do about this?
EDIT: In the duplicate issue the person writes their own dll. I don't own the dll I'm having problems with and I can't change it.
You can try to grab the path directly from the executable if CurrentDirectory is giving you an issue:
private void GetFilePath()
{
string filepath = string.Empty;
var processes = Process.GetProcessesByName("exe name");
foreach (var process in processes)
{
filepath = process.MainModule.FileName;
}
return filepath;
}

How can I fix this DirectoryNotFoundException?

I have a DirectoryNotFoundException on a .txt file if I use the full path it's working but I don't want to use the full path because I want the program work no matter where it is placed (compatibilty with the maximum of computer)
Here's my code
private void SaveClose_Click(object sender, RoutedEventArgs e)
{
if (Windowed.IsChecked == true)
windowed = true;
else
windowed = false;
string textWriteWindowed;
if (windowed == true)
{
textWriteWindowed = "-screen-fullscreen 0" + Environment.NewLine;
}
else
{
textWriteWindowed = "-screen-fullscreen 1" + Environment.NewLine;
}
var selectedResolution = ResolutionBox.SelectedItem.ToString();
var split = selectedResolution.Split('x');
widthChoose = Int32.Parse(split[0]);
heightChoose = Int32.Parse(split[1]);
string textWriteWidth;
textWriteWidth = "-screen-width " + widthChoose + Environment.NewLine;
string textWriteHeight;
textWriteHeight = "-screen-height " + heightChoose + Environment.NewLine;
File.WriteAllText(#"\Resources\arguments.txt", textWriteWindowed);
File.AppendAllText(#"\Resources\arguments.txt", textWriteWidth);
File.AppendAllText(#"\Resources\arguments.txt", textWriteHeight);
this.Close();
}
The first argument of File.WriteAllText takes a path as input. Whatever you have mentioned is not the absolute path but it is just the relative path of the file. WriteAllText creates the file but doesn't create the directory by itself. So something like:
File.WriteAllText(#"\arguments.txt", textWriteWindowed);
shall work (and create the file in the respective drive), but
File.WriteAllText(#"\Resources\arguments.txt", textWriteWindowed);
shall not work. Hence, if you want to create a file in the path where the application resides, you can do something like:
string folder=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
File.WriteAllText(#"\arguments2.txt", "ABC");
If you want to create a directory, then you could do something like:
System.IO.FileInfo file = new System.IO.FileInfo(filePath);
file.Directory.Create();// If the directory already exists, this method does nothing.
System.IO.File.WriteAllText(file.FullName, textWriteWindowed);
Hope this answers your query.
you have to check whether the folder is exist before save the file,
if folder not exist create it using
Directory.CreateDirectory(...)
Directory.Exists(..)
you can use to check folder existence
IF you wanted to get the local path of the file you are executing use this:
var fInfo = new FileInfo(System.Reflection.Assembly.GetCallingAssembly().Location);
From there, you would do the following:
var parentDir = new DirectoryInfo(fInfo.DirectoryName);
var subDir = new DirectoryInfo(parentDir.FullName + "Resource");
if(!subDir.Exists)
subDir.Create();
This would ensure that you always have a folder in the directory of your executable. But just so you know, this is absolutely horrible code and should never ever be implemented in a production like environment. What if some knucklehead sysAdmin decides to place your program/folder in an area that the current user does not have access/writes too? The best place to write to is %APPDATA%, this will ensure the user always has read/write permissions to what you are trying to accomplish.
I don't know how but doing that worked for me :
File.WriteAllText(#"./arguments.txt", textWriteWindowed);
File.AppendAllText(#"./arguments.txt", textWriteWidth);
File.AppendAllText(#"./arguments.txt", textWriteHeight);

Delete a file which is used by another process in c#

I am trying to delete one file which was used by certain another process of my Application.
So its giving an Error that file is used by certain another process.
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
DirectoryInfo NewDir = new DirectoryInfo(imagefolderpath1);
FileInfo[] files = NewDir.GetFiles("*.jpg");
foreach (var item in files)
{
string strFile = imagefolderpath1 + "\\" + item.ToString();
if (File.Exists(strFile))
{
File.Delete(strFile);
}
}
}
How should i solve this problem can you please help me????
You need to kill the process which is causing this issue by the following code, something like :
string fileName = #"D:\pathname.jpg";//Path to locked file
Process Handletool = new Process();
Handletool.StartInfo.FileName = "handle.exe";
Handletool.StartInfo.Arguments = fileName+" /accepteula";
Handletool.StartInfo.UseShellExecute = false;
Handletool.StartInfo.RedirectStandardOutput = true;
Handletool.Start();
Handletool.WaitForExit();
string outputTool = Handletool.StandardOutput.ReadToEnd();
string matchPattern = #"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
foreach(Match match in Regex.Matches(outputTool, matchPattern))
{
Process.GetProcessById(int.Parse(match.Value)).Kill();
}
u can get Handle.exe from http://technet.microsoft.com/en-us/sysinternals/bb896655.aspx
The file needs to be released by the other program before it can be deleted. You can use Process Explorer to find out what is locking it if you don't know.
you can't access the file used by another process. But if it's not critical for you app to do this later, you can do this in the System.AppDomain.ProcessExit event handler.
just add the file to a centrally managed list and register your cleanup routine like here:
AppDomain.CurrentDomain.ProcessExit += new EventHandler(deleteFilesIfPossibleNow);
in the handler you must still handle exceptions if files are still accessed from another processes.
instead of using _FormClosed you might want to try launching the form from your other code like this:
DirectoryInfo NewDir;
FileInfo[] files;
using (var form = new Form1())
{
var result = form.ShowDialog();
if (result == DialogResult.Close)
{
NewDir = new DirectoryInfo(imagefolderpath1);
files = NewDir.GetFiles("*.jpg");
}
}
foreach(var item in files) {
string strFile = imagefolderpath1 + "\\" + item.toString();
File.Delete(strFile);
}
i wasn't a hundred % sure how your program is meant to work but you can grab information from the forms before they close then close the files they were using after with this kind of method

How can I recursively count files and folders in Windows with C#?

EDIT 8/8/2012: I've made some significant changes to the code I'm using and would like some fresh help on one last problem I'm having. I'm going to rewrite most of this question.
I have a small program which iterates recursively through each file and folder under a target directory checking the names for specific characters. It works just fine but I'm looking for help on how to make a specific method work faster.
Here's the code I'm currently using. This is just a couple of lines from the method that kicks everything off:
if(getFullList(initialPathTB.Text))
SearchFolder();
And these are the two methods you need to see:
private void SearchFolder()
{
int newRow;
int numItems = 0;
numItems = itemsMaster.Length;
for (int x = 0; x < numItems; x++)
{
if (hasIllegalChars(itemsMaster[x]) == true)
{
newRow = dataGridView1.Rows.Add();
dataGridView1.Rows[newRow].Cells[0].Value = itemsMaster[x];
filesFound++;
}
}
}
private bool getFullList(string folderPath)
{
try
{
if (checkBox17.Checked)
itemsMaster = Directory.GetFileSystemEntries(folderPath, "*", SearchOption.AllDirectories);
else
itemsMaster = Directory.GetFileSystemEntries(folderPath, "*", SearchOption.TopDirectoryOnly);
return true;
}
catch (UnauthorizedAccessException e)
{
if(folderPath[folderPath.Length - 1] != '\\')
folderPath += #"\";
if (e.Message == "Access to the path '" + folderPath + "' is denied.")
{
MessageBox.Show("You do not have read permission for the following directory:\n\n\t" + folderPath + "\n\nPlease select another folder or log in as a user with read access to this folder.", "Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Error);
folderPath = folderPath.Substring(0, folderPath.Length - 1);
}
else
{
if (accessDenied == null)
accessDenied = new StringBuilder("");
accessDenied.AppendLine(e.Message.Substring(20, e.Message.Length - 32));
}
return false;
}
}
initialPathTB.Text is populated with something like "F:\COMMON\Administration".
Here's my problem. When the top level that's passed to folderPath is one which the user does not have read access everything works fine. When the top level and all subordinate directories are folders which the user has read access everything works fine again. The issue lies with directories where the user has read access to the top level but does not for some child folder deeper within. This is why getFullList() is a bool; if there are any UnauthorizedAccessExceptions then itemsMaster remains empty and SearchFolder() fails on numItems = itemsMaster.Length;.
What I'd like is to populate itemsMaster with every item within folderPath and simply skip the items for which the user doesn't have read access but I don't know how to do that without recursively crawling and checking each directory.
This code works so much faster than my old method so I'd rather not abandon it for something else entirely. Is there any way to make the Directory.GetFileSystemEntries() method do what I want?
Directory.GetFileSystemEntries(folderPath, "*", SearchOption.AllDirectories).Length
or another option (with this option, keep in mind the first 3-5 elements in fullstring will be garbage text from the output which you should remove):
Process process = new Process();
List<string> fullstring = new List<string>();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived += (sender, args2) => fullstring.Add(args2.Data);
process.Start();
process.StandardInput.WriteLine(#"dir /b /s c:\temp | find """" /v");
process.BeginOutputReadLine();
process.WaitForExit(10000); //or whatever is appropriate time
process.Close();
If you want to track down errors better, make these changes:
Declare List<string> fullstring = new List<string>(); globally, then change the event handler of OutputDataReceived like below:
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
}
static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
try
{
fullstring.Add(e.Data);
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
//log exception
}
}
You write that "I'd like the progress bar to actually indicate how far through the list of items the program is, so therefore I need a number of items to set the ProgressBar.Maximum property to."
This is kind of a specific desire, and I'm not sure its worthwhile in the given case. If your ProgressBar is (say) 800 px wide, 1 percentage point would be 0.125px wide. For a list "over a hundred thousand items" -- let's make that a minimum of 100,000 -- you have to process 8,000 items to move the bar to move a single pixel. How much time does it take for your program to process 8,000 items? That will help you understand what kind of actual feedback you're giving the user. If it takes too long, it might look like things have hung, even if it's working.
If you're looking to give good user feedback, I'd suggest setting your ProgressBar's style to Marquee and providing a "Now checking file #x" textual indicator.

"Could not find part of the path" error when copying a file

I've googled about this all over the Internet and still haven't found a solution. As an ultimate try, I hope someone can give me an exact answer.
I get that error when I try to copy a file from a directory to another in an File Explorer I'm trying to do on my own. It has a treeview control to browse for directories and a listview control to display the contents of the directory. This is how the code would look like, partially:
private void copyToolStripMenuItem_Click(object sender, EventArgs e)
{
sourceDir = treeView1.SelectedNode.FullPath;
for (int i = 0; i < listView1.SelectedItems.Count; ++i)
{
ListViewItem l = listView1.SelectedItems[i];
toBeCopied[i] = l.Text; // string[] toBeCopied, the place where I save the file names I want to save
}
}
private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
{
targetDir = treeView1.SelectedNode.FullPath;
try
{
for (int i = 0; i < toBeCopied.Length; ++i)
{
File.Copy(sourceDir + "\\" + toBeCopied[i], targetDir + "\\" + toBeCopied[i], true);
refreshToolStripMenuItem_Click(sender, e);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + Environment.NewLine + ex.TargetSite);
}
}
The place where I got the error is at File.Copy(sourceDir + "\\" + toBeCopied[i] ....
I've read that it could be something that has to do with the mapping of devices, but I don't really know what that is.
Can you take a look at the Path.Combine method on MSDN? This will help make sure all your entire path doesn't have extra \'s where they shouldn't be.
i.e. Path.Combine(sourceDir, toBeCopied[i])
If you are still getting an error, let me know what the value if the above.
Does the target path up to the file name exist? File.Copy() will not create any missing intermediate path, you would need to do this yourself. Use the debugger to see both the source and target paths you are creating and make sure the source exists and the target exists at least up to the parent of the target file.
You do not show where toBeCopied is created. It looks like you are probably running past the end of the values that are set in the click event, and trying to copy a bunch of files with empty names.
You should add this to the beginning of your click event
toBeCopied = new string[listView1.SelectedItems.Count];
Also (as others have noted) instead of
sourceDir + "\\" + toBeCopied[i]
you should use
Path.Combine(sourceDir, toBeCopied[i])
Assuming both sourceDir and targetDir exist (which you can and should check), you might be doubling up a trailing \. When building paths, you should use Path.Combine.
File.Copy(Path.Combine(sourceDir, toBeCopied[i]), Path.Combine(targetDir, toBeCopied[i]), true);
Borrowing from Henk's loop, but I'd add the file & directory checks, since it is the path not found errors that need checking/creating that the OP has the problem with.
for (int i = 0; i < toBeCopied.Length; ++i)
{
string sourceFile = Path.Combine(sourceDir, toBeCopied[i]);
if(File.Exists(sourceFile))
{
string targetFile = Path.Combine(targetDir, toBeCopied[i]);
if(!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
File.Copy(sourceFile, targetFile, true);
}
refreshToolStripMenuItem_Click(sender, e)
}

Categories

Resources