I would like to know if there is any way to set a position and a size of a ClickOnce deployed application, started via Process.Start. With normal (.exe) applications there is no problem, I can do something like that:
var externalAppProcess = Process.Start("calc");
var externalAppPtr = externalAppProcess.MainWindowHandle;
and then use invoked MoveWindow to set stuff like position, size etc. However, when I'm starting an appref-ms file, it runs without any issues, but I can't access its MainWindowHandle, it says that "Process has exited, so the requested information is not available". Any ideas?
When you launch *.appref-ms, rundll32 or dfshim process will run. It does ClickOnce checking and eventually starts executable of ClickOnce deployed application.
So you may try finding main window handle like this:
var processes = Process.GetProcessesByName("ClickOnceDeployedApp");
foreach (Process p in processes)
{
IntPtr windowHandle = p.MainWindowHandle;
// do something
}
Related
I'm developing a very simple 3rd party anti-cheat app in C#. I've managed to create a code that will scan any .exe for forbidden strings like "aimbot" and "hack". But the way I did it is, you browse for a file to scan and click a button to scan it - and this works great. What I want now is that my tool will check the running user processes and scan them automatically. Is that even doable?
If you already know the process names you want to go for, you can go with this.
Process[] processMame = Process.GetProcessesByName("yourProcess");
if (processMame.Length > 0)
{
/// You got your process here
/// Do whatever you want
}
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
Console.WriteLine($"Process: {process.ProcessName} ID: {process.Id} Path: {process.MainModule.FileName}");
}
You might want to make sure your app runs on administrator mode to do so. If you want the executable path you'd find it here on process.MainModule.FileName
Update:
I tried out opening a running executable and I was right on the fact that I would end up in an access violation even if Im administrator as that file is being used by other process now.
My suggestion would be if you want to check out an existing process, kill/dispose it, open it and do whatever you're supposed to do and if you feel this is not harmless, you restore it back.
You might need to make sure that your app has administrator privileges through manifest defined here.
For going for processes in current session:
If you want to have the processes in current active session (current active user who is logged in), you might want to go for something like:
Process[] runningProcesses = Process.GetProcesses();
var sessionId = Process.GetCurrentProcess().SessionId;
var currentSessionProcesses = runningProcesses.Where(c => c.SessionId == sessionId).ToList();
foreach (var process in currentSessionProcesses)
{
Console.WriteLine($"Process: {process.ProcessName} ID: {process.Id} Path: {process.MainModule.FileName}");
}
link app with windows process so that when user terminated or end the process it says used by another process and also need to insert it into system file like shutdown file using c sharp so that my app never end or terminates
i tried that material but not usefull
this.ShowInTaskbar = false;
I also tried that code in click:
WindowsImpersonationContext ctx = null;
if (!WindowsIdentity.GetCurrent().IsSystem)
{
ctx = WindowsIdentity.Impersonate(System.IntPtr.Zero);
}
string thisuser = WindowsIdentity.GetCurrent().Name;
But have a look at image it is still present in process, what I want is that my process never stops.
what I want is that my process never stops.
To ensure that your process is always running and is started when Windows boots it's easiest to create a windows service instead. It will probably still show up somewhere in task manager and could be killed manually by the user. But windows will try to keep it running.
How to create a service:
https://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx
And if you need other programs to communicate with your service I find it easy to use a WCF service instead.
https://msdn.microsoft.com/en-us/library/bb386386.aspx
I need to interact with another application, that resides in the tray.
I'm currenty using TestStack White this way:
ProcessStartInfo processStartInfo = new ProcessStartInfo("MyProg.exe");
Application application = Application.AttachOrLaunch(processStartInfo);
_window = application.GetWindows()[0];
Everything works if the application was not running before this call, since launching it, this is visible.
Instead, if the application was already running, and in the tray, White could not find any window, and I can see this in the console as the following log:
Could not find any windows for this application
...and, after some retries, it fails with an exception.
Now, the best solution I found is to kill the application and relaunch it:
application.Kill();
application = Application.Launch("MyProg.exe");
and this works.
But I guess there is a better solution to this.
Open the application you want to automate and print all the running process names, find which stands for the application.
The add the following code...
Application myApp;
myApp = Application.Attach("ProcessName");
Hope it helps...
Did you try attaching to the explorer.exe process?? Since the system tray icon for the app will reside under the explorer.exe.
Something like this:
Did you try attaching to the explorer.exe process?? Since the system tray icon for the app will reside under the explorer.exe.
Something like this:
Process _explorerProcess = Process.GetProcessesByName("explorer")[0];
application = Application.Attach(_explorerProcess.Id);
Window desktopWindow = application.GetWindows()[0];
You should then be able to interact with the system tray icon.
i am trying to start a browser instance as a process from a c# code. then i want to kill the same instance of the browser. I tried finding the same instance with process id . But the process ids are different in task manager and the initial id which i got when i started the process.
what's the solution? why is this happening? Development enviorment is windows 7.
int ID= 0;
void Start()
{
ProcessStartInfo startInfo = new ProcessStartInfo("iexplore.exe");
startInfo.Arguments = "http://www.google.com";
Process ieProcess = Process.Start(startInfo);
ID= ieProcess.Id;
}
void Stop()
{
foreach (Process p in System.Diagnostics.Process.GetProcessesByName("iexplore"))
{
if ((p.Id == ID))
{
p.Kill();
}
}
This code will not work if IE is already launched. Close all IE browsers and then try to run the code. If it works then you may have to look for solution suggested in following link
similar post-
Process.kill() denied in Windows 7 32bits even with Administrator privileges
Why don't you add your code to the question? It'll make life easy for the people who are interested in helping you. If you get different PIDs, most probably there's something wrong with your code! (I'm just guessing without seeing what you have tried.)
Have a look at these questions as well.
1) Getting PID of process started by Process.start()
2) Programmatically kill a process in vista/windows 7 in C#
3) Process.kill() denied in Windows 7 32bits even with Administrator privileges
Adding the code makes it much easier to understand what the problem is and here's your problem.
IE creates more than one process for one instance of the program. (more details about it) That's why you get different PIDs (for the different processes).
What your code does is killing only one process of it (by the usage of if condition in the Stop() method!). So the remaining process may generate InvalidOperationException when you try to execute Start() again(starting the same process)!
So what your code should do is kill all the active iexplore processes. This can be done by simply removing the if condition of Stop() method.
foreach(Process p in Process.GetProcessesByName("iexplore"))
{
p.Kill();
}
Let me know whether this worked.
I have a similar issue, only I dont want to kill the IE process that I started, I want to bring it into focus.
I have one app that starts 5 IE windows.(not tabs, but unique windows)
I store the PIDs that I start each of the IE windows with.
At particular times, I want to be able to:
select a PID,
find the IE window related to that PID
bring it into focus (minimizing the others)
This worked using XP and IE6 (required for the environment)
Now when I am using Win 7 and IE 8, the PID that I stored is not found,
and thus I no longer have the ability to change the window in focus.
I am writing a program (Visual Studio 2010 in C# Windows Forms) which keeps track of multiple instances of the Remote Desktop Client (mstsc.exe - tested with Windows 7 version). I have been attempting to launch this program and grab its PID with the following code:
Process mstsc = Process.Start(mstscLocation, mstscConString);
int mstscProcessId = mstsc.Id;
DataRow row = openConn.NewRow();
row["RDP ID"] = mstscID;
openConn.Rows.Add(row);
This starts the client and returns an ID as it should. Problem is, if I try to terminate the PID with the following code, it fails to do so:
int rdpID = Convert.ToInt32(dgvOpenConnections.Rows[selectedIndex].Cells["RDP ID"].Value.ToString());
try
{
// kill off mstsc
Process mstsc = Process.GetProcessById(rdpID);
mstsc.Kill();
}
I have verified that the PID that is recorded from Process.Start is the same as is retrieved from the DataGridView (dgvOpenConnections) and placed into rpdID (try fails and hits catch as the original PID no longer exists). Furthermore, I have issued a "tasklist" at a command prompt after starting one instance of MSTSC.EXE and can verify that it changes PIDs (in this test, C# recorded 4288 but tasklist shows it running as 8172).
I cannot kill all MSTSC processes as I am trying to control more than one. Is there a way to trace down the second PID MSTSC appears to use? My guess is it either starts a second process and gets rid of the first or maybe this is a child process (although the PID that is return no longer exists after start).
How in C# can I ensure I have the right process ID to later monitor or kill a specific instance of the Remote Desktop Client?
This happens if you try to run mstsc from a 32-bit application in 64-bit Windows.
(Source: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/22c10140-a502-4aa1-98d3-3607b8b573e8/)
There are two versions of mstsc on a 64-bit Windows:
c:\windows\system32\mstsc.exe is a 64-bit version
c:\windows\syswow64\mstsc.exe is more or less a "redirect" that will open c:\windows\system32\mstsc.exe from a different process than your application.
I've had the same issue. My application started mstsc, the process immediately exited, and mstsc reappeared with a different parent process and different PID.
This happens because 64-bit Windows uses file system redirection to redirect calls to the 64-bit c:\windows\system32 executables to c:\windows\syswow64.
There are two solutions:
Recompile your application to 64-bit. Then your application will also use the 64-bit mstsc.
Disable file system redirection (see http://blog.tonycamilli.com/2005/07/disabling-wow64-file-system.html) and access the 64-bit mstsc from your 32-bit application.
I have only tried recompiling, and it worked. :-)
Edit:
If you don't want your users to use the right version (we're using ClickOnce deployment, so we'd rather send one link to everybody), here's a workaround:
If you're using an .RDP file for mstsc, just add a unique token to your file name. mstsc will be started with a command line like mstsc host_user_token.rdp.
Now, after you called Process.Start, do Process.WaitForExit with a short timeout (5s). If the process did not exit, you have the right object.
If the process did exit, do a little polling loop (100ms interval, 5s timeout) that checks for processes with your token:
var timeout = AppSettings.GetIntValue(
Constants.SettingsKeyProcessFinderTimeout, Constants.ProcessFinderTimeoutDefault);
int elapsedTime = 0;
Process process = null;
while (elapsedTime <= timeout)
{
process =
Process.GetProcessesByName("mstsc").FirstOrDefault(p => p.StartInfo.Arguments.Contains(guid));
Logger.TraceVerbose(
string.Format(
"Elapsed time: {0}; Found process with PID {1}", elapsedTime, process == null ? -1 : process.Id));
if (process != null)
{
break;
}
Thread.Sleep(SleepInterval);
elapsedTime += SleepInterval;
}
After that loop, if you still have process == null, there was some error (process was not found or never executed at all). If you have a Process reference, that's the "new" mstsc process.
I tried your example using Process Explorer, and I couldn't see a second or child process being created. From beginning to end the Remote Desktop Process was one and the same, and after being created I was able to kill the process using the same PID I saw in the beginning.