I want to insure mutual exclusion in my project for installing updates.
The project is multi-instance means one can open a instances without closing the other open instances. There is a function called installUpdates() which installs the available updates. Since several instances are there so only one of them need to install the updates. I want to insure that only one instance will install the updates.
I am taking a variable globally called noOfInstances(semaphore) initialized to 0. Once a new instance is opened the variable will be incremented by 1. If there are 4 open instances then the value of noOfInstances will be 4. Once a instance is closed the value will be decreased by 1. For installing the updates I am writing:-
if(noOfInstances == 1)
{
InstallUpdates();
}
Now my problem is that how to track programmatically that there is an instance opened of my project? There may be some unique Id for each instance which I am not able to identify. I am using windows environment to develop my c# application.
A global Mutex is probably a better mechanism to gate access to exactly-once-only functions. In this instance I'd try acquire a mutex with a short timeout. If you fail to acquire it - someone else has it. If you succeed, test if updates are necessary, and if so install updates.
An optimization might be to move the test outside of the mutex - but you'll still need to retest if updates are required inside the scope of the mutex.
What is a good pattern for using a Global Mutex in C#?
You can use Process.GetProcesses to get processes by name
var processes = Process.GetProcesses Method (ProcessName)
if (processes!= null)
{
int runningInstances = processes.Length;
}
While I've implemented #stephbu's mutex-pattern in the past, requirements recently have been that the running instance should be brought to the front if the program was started twice.
To do so, I try to connect to a named pipe. If I can not connect, this is the first instance and I create the named pipe and then do things normally. If I can connect, this is a second instance and I send a command via the pipe and quit.
Receiving a command on the named pipe I can do anything I want, like bring the main window to the top.
This solution, however, only makes sense if you actually want to do something with the pipe as described above. If you only want to prevent the application from being run twice, #stephbu's mutex answer is the way to go.
You can get the Running Processes like this :
using System.Diagnostics;
int GetInstanceCount(ExeName)
{
Process[] processlist = Process.GetProcessesByName(ExeName);
int NoOfInstances = processlist.Count;
return NoOfInstances;
}
Now Implement Like This:
string ExeName = "notepad.exe"//Say Notepad
if(GetInstanceCount(ExeName) == 1)
{
InstallUpdates();
}
Related
How can i check if another instance is running ?
Also if it is running how can I force my already opened instance to open a file ?
Also if it is possible can I force it to get focus? ( I need this seperate)
How can i check if another instance is running ?
You could use Process.GetProcesses() to get a list of processes which are running on your machine. And simply do your compare with Process.Name. With rather simple name, you may need additional check for your application.
Also if it is running how can I force my already opened instance to
open a file ?
If you want to communicate between 2 processes, I would recommend SendMessage method. See here.
Also if it is possible can I force it to get focus? ( I need this
seperate)
You could use SetForgoundWindow method (also require P/Invoke). See here.
I'm building an IronPython module that initializes an instance of AutoCAD and I need to return 1 to the module calling it after AutoCAD has finished initializing, entered its message loop and is in a stable (not loading dependencies/anything) state. I've tried using System.Diagnostics.Process.WaitForInputIdle() with no luck.
Here's what I have so far:
import System.Diagnostics as sysdiag
def start_autocad(self):
print("\"C:\\Program Files\\Autodesk\\Autodesk AutoCAD Civil 3D 2014\\acad.exe\" /b \"C:\\Temp\\C3DAutoScript.scr\"")
for process in sysdiag.Process.GetProcessesByName("acad"):
process.Kill()
try:
acad_process = sysdiag.Process.Start("C:\\Program Files\\Autodesk\\Autodesk AutoCAD Civil 3D 2014\\acad.exe", " /b \"C:\\Temp\\C3DAutoScript.scr\"")
acad_process.WaitForInputIdle()
return 1
except:
return 0
Unfortunately, this function as it stands returns as soon as the process begins opening, not after it's done. Does anyone know a way to handle this either in classic cPython, IronPython or C# (without using an overkill sleep function to wait for it)?
A process can start processing messages almost immediately after start up. There is no requirement that the main window is displayed before this is done. This can be done to avoid being displayed as hanging, in case loading is slow.
You can either try interacting with the process after WaitForInputIdle returns — it may eventually respond even while "loading". If it doesn't work, wait for the main window to appear (using FindWindow). If the application is COM server, you try establishing COM connection.
P.S. Killing processes is not the best idea and may result in corrupted data or configuration. Try closing application properly be sending close event to its main window.
In the title of your question you ask for "a process". In the text of your question you ask specifically for Autocad.
I can tell you how to do it for a process in general, not specifically for Autocad.
I had the same problem and came to the solution to use the API
GetModuleFileNameEx(HANDLE h_Process, ....)
MSDN says:
If the module list in the target process is corrupted or is not yet
initialized, or if the module list changes during the function call as
a result of DLLs being loaded or unloaded, GetModuleFileNameEx may
fail or return incorrect information.
And in deed when you try to get the executable path of the process with this function while the process is still loading it's DLL's the function fails and GetLastError() returns ERROR_INVALID_HANDLE. This does not mean that the process handle that you pass to the function is invalid. But this is the error code you get when the process is still starting up.
I tested it with several applications. It works perfectly.
int WaitForProcess(HANDLE h_Process, int Timeout)
{
for (int T=0; T<=Timeout; T+=50)
{
if (GetModuleFileNameEx(h_Process, NULL, ...) > 0)
return 0;
int Err = GetLastError();
if (Err != ERROR_INVALID_HANDLE) // = 6
return Err;
Sleep(50);
}
return ERROR_TIMEOUT;
}
Why does it work? What GetModuleFileNameEx() does internally is to read the memory of the process (for that you must open the process with access permission PROCESS_VM_READ). But this is not allowed while the process is in the loader lock. The loader lock is active while a process is loading DLL's.
This code is general and works for any application. It waits until the application is ready with it's basic initialization. If this is not enough for you I recommend to wait for the main window of the application to appear.
I wrote a main program in C#, and I worte also a small tool program also in C#.
I want that the tool program will be able to execute under some conditions:
When called from my main program.
When called from open some suffix of file (e.g. "*.abc")
But if the user open my program directory he can run the tool program, and I do not want him to be able to do it. I want him to be able to run the program under the conditions above. And if he ran the program manually, the program automatically shut.
Is there any way to do that?
To check if your main program called it, you could pass the main program's ProcessID as a commandline argument, then in your small program, check if that ProcessID exists and if its process name is the name of your main program. This isn't spoof-proof, but might be a bit trickier to fake than just passing a static number/string.
In addition, you could encrypt the number and pass that, then decrypt it and check the above. It's pretty much impossible to prevent a determined hacker from running your program on its own, but you can raise the bar of how tricky it is to do it. You'd also want to obfuscate your code, otherwise a quick Reflector call will show exactly what characters are being passed.
Alternatively, if possible, you could just make the small program a DLL and call it from your main program like that. This would need a bit of refactoring, but would force your program to be open. As for opening a *.abc file, your program can check the command line arguments to see if a filename was passed through. This can then be processed automatically by your app and the DLL calls can be made.
There is nothing exposed to the process/executing environment that tells it how it was invoked, so there is no foolproof way to do this.
You can have your main program pass in a flag on the command line - this and the suffix are things that you can check for and if either one does not exist you terminate immediately.
However, if the user ever guesses the flag, they can still call the application directly.
Other mechanisms could involve writing a value to a file from your main program just before invoking the second program and checking that file from your second program (and deleting it after execution), as a messaging mechanism. There are other messaging mechanisms that would do similar things (private MSMQ queues for instance).
You can use a named mutex with some hard-to-guess name to make sure that the "small tool" program was called by the main program. So, you create a Mutex in your parent program:
bool requestInitialOwnership = true;
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex",
out mutexWasCreated);
Then in your child program you write the exact same code to check if the parent program executed it. If mutexWasCreated==true, then it was not called by the parent program. Otherwise, it was.
Checking the arguments passed to the program will help to determine whether the filename's extension is .abs or not.
We have a product that is a C# console app. Is it possible to restrict it to run from the command line only? In other words, users wouldn't be able to call it from a script or another app.
If it is, some example code would be much appreciated. Thanks.
You can check the process that created your application using the code given here: http://msdn.microsoft.com/en-us/netframework/aa569609.aspx#Question3 . To be started at the DOS command line the parent process should be cmd.exe. Note however as pointed out by Colin this can be bypassed easily using a batch script. You can disable that as well by making sure that the command prompt arguments to cmd.exe are null. For this you will need to use WMI :
http://skysanders.net/subtext/archive/2010/04/11/using-wmi-to-fetch-the-command-line-that-started-all.aspx
You should also check the cmd.exe image is from system32 folder.
I don't think it is possible to tell the difference.
Certainly the parent process is not a useful indicator. This is what you get in the parent process:
1. type app name into Command Prompt: cmd.exe
2. call app from batch script: cmd.exe
3. Double click on app or shortcut: explorer.exe
4. type app name into Run dialog box: explorer.exe
If you intend for 1. to be a valid way to start your program, then I don't think you can stop 2. which means your app can be called from any script or any program (since it's simple for another program to create a 1 line batch script and execute it)
(BTW, does anyone know a way to get a table on StackOverflow?)
#swisston if you start your console application from your another own application, than i want to recommend you "named kernel objects". For example mutex. You can create named mutex in your parent app. Then in main thread of your child console app try to open this mutex. If mutex not opened (not found): console app has no permissions to continue and must be closed;) wait, i'll make some code for you;)
Edit:
So it is very easy tactics. In parent app create your named mutex:
Mutex mutex = new Mutex(true, "MyPermissions");
Then in your child console application check if your mutex exists:
static bool CheckPermissions()
{
try
{
Mutex mutex = Mutex.OpenExisting("MyPermissions");
}
catch (Exception ex)
{
return false;
}
return true;
}
If your console application was run without your parent application CheckPermissions method will return false and console must be closed;)
I don't agree with what you're trying to do, but here is an idea that could work: require some sort of user input at the beginning of the program, maybe some sort of CAPTCHA (difficult to do in command line, but theoretically possible. Think ASCII art).
I have some UI application that lives in the user's task bar that is written in C#. The EXE for the tool is checked in to our source control system on a number of projects that use it so we are able to update the version they run with by checking in updated EXE.
The problem is that when the users get the latest revision of the exe, the program is often running, and the sync fails on their machine. I want to fix it so the program doesn't lock the exe and any dependent DLL's when it runs so they can sync without having to shut down the program.
Currently, I have a program that takes an executable as a parameter and will launch it from memory by reading the assembly contents into memory ahead of time. Unfortunetly, this totally fails when it comes to the DLL's that the program requires.
The code I have right now looks something like this:
public class ExecuteFromMemory
{
public static void Main(string[] args)
{
//Figure out the name of the EXE to launch and the arguments to forward to it
string fileName = args[0];
string[] realArgs = new string[args.Length - 1];
Array.Copy(args, 1, realArgs, 0, args.Length - 1);
//Read the assembly from the disk
byte[] binary = File.ReadAllBytes(fileName);
//Execute the loaded assembly using reflection
Assembly memoryAssembly = null;
try
{
memoryAssembly = Assembly.Load(binary);
}
catch (Exception ex)
{
//Print error message and exit
}
MethodInfo method = memoryAssembly.EntryPoint;
if (method != null && method.IsStatic)
{
try
{
method.Invoke(null, new object[] { realArgs });
}
catch(Exception ex)
{
//Print error message and exit
}
}
else
{
//Print error message and exit
}
}
}
My question is, am I doing something totally stupid? Is there a better way to handle this? If not, what should I do to support handling external dependencies?
For example, the above code fails to load any dependent files if you try to run 'Foo.exe' that uses functions from 'Bar.dll', the 'Foo.exe' will be overwriteable, but 'Bar.dll' is still locked and can't be overwritten.
I tried getting the list of referenced assemblies from the 'GetReferencedAssemblies()' method on the loaded assmebly, but that doesn't seem to give any indication where the assemblies should be loaded from... Do I need to search for them myself? If so, what's the best way to do this?
It seems like other people might have come across this before, and I don't want to re-invent the wheel.
-
Update:
The EXE is checked in because thats how we distribute our in-house tools to the teams that use them. Its not optimal for this use-case, but I don't have the opportunity to change that policy.
Disclaimer: I don't use Windows, though I am familiar with its strange way of locking things.
In order to update your application while it is running, you'll likely need to have two processes: The executable itself, and an update “helper” application that will finish the update process. Let's say that your application is ProcessA.exe and your update helper is Updater.exe. Your main program will download a new copy of the executable, saving it with a random name. Then you run your updater program, which watches for the termination of your current process. When your process terminates, it displays a quick window showing the status of the update, moving the new executable into the place of the old one, and then restarting that program.
It'd be more elegant to be able to emulate POSIX filesystem semantics and be able to delete the currently-running process disk image and replace it with a new file, but I don't know if that is even possible on Windows. On a POSIX system, you can delete an in-use file and it won't actually be deleted until any remaining file handles are closed, though you can then reuse the filename.
You might want to check out an article written at CodeProject that talks about this. It also has a follow-up article.
Good luck!
Does the program need to keep running while updating?
Typically to update a program which is running you would copy over any of the files that are to be replaced to a temporary folder. Then shut down the old instance, delete it and move the new files over to the correct locations then re-launch it.
This allows for minimal down time of the application since the longest part is usually the copy and the file move is very fast if the temporary folder is on the same logical drive.
Although Michael's answer is one way of doing this, there are tools out there that are explicitly for managing what's installed on the desktop.
What you are doing with the exe being checked into source control is not normal. If you have a windows domain controller, you can use Group Policy to push programs down to the client. Alternatively, you could use something like Altiris to handle it.
If you must continue the way you are going then you have two options. One, using a helper / loader app which does a version check on launch. This is similar to how firefox works.
The second way is to build a helper service that sits in memory and polls every so often for updates. This is how Google Chrome, Adobe, etc work.