Get custom status of process - c#

I want to allow multiple processes of my application on one machine.
Projects (come from local database) can be loaded in each process and I want to ensure that a Project can only be open in one process of my application.
Therefore before opening a Project I want to check if the Project I want to open is already open in another process.
I know that this isn't best programming practice, but I it's just a temporary solution until we implement a more sophisticated locking mechanism on data Level.
I can detect another running process, but can I somehow access or cast it to something more appropriate to get the Information I want ?
Someting like that:
Process[] allProcesses = Process.GetProcessesByName("MyApp");
foreach (Process process in allProcesses)
{
var projects = process.OpenedProjects;
Have come across .net remoting, WCF, IPC but found that to be very heavyweight for this rather "simple" Task.

If it's a temp solution, just choose the easy way:
When a process load a project, just write a file in the app directory with the project name or ID. If the file already exists it means the project is already loaded in another process.
You can also write the process ID as file content, if you want to know which process have opened a project.
Of course you need to delete the file when the process finish.
Be sure that you handle all exceptions so that process can't finish without deleting this file. I.e. intercept AppDomain.UnhandledException.

If this is a temporary solution as you say, you could give each project an identifier (e.g. filename) and display it in the title of the main window, for example
C:\Project1.proj C:\Project2.proj C:\Project3.proj
Then check if the project is open with process.MainWindowTitle.Split(' ').Contains.

Related

Passing stream objects / file handles between two processes in .NET

I have a windows service and a desktop application running on the same machine. The app pre-processes some documents and transfers them to a folder where the service can take over. When the app is creating the new file for the service, it keeps a read-only lock on the file while writing. It them releases it so that the service can acquire a new read-only lock (FileStream).
I'd like the app to somehow hand-over this lock to the service without closing it. Is this possible in the managed runtime? If not, is there a way to P/Invoke this behaviour?
The reason this behaviour is desired is so that no other processes can modify or delete the file until both the app and service are done with it.
This is not possible in a managed-only way.
Try to use a simpler approach, such as naming the file with a random name in a temp directory such that no other application will try to open it.
If you insist on passing the handle, you must duplicate the handle into the service process and pass the numeric handle value of that process to the service process. Use OpenProcess, DuplicateHandle and CloseProcess for that.
From http://msdn.microsoft.com/en-us/library/windows/desktop/ms724251(v=vs.85).aspx:
The duplicate handle refers to the same object as the original handle.
Therefore, any changes to the object are reflected through both
handles. For example, if you duplicate a file handle, the current file
position is always the same for both handles. For file handles to have
different file positions, use the CreateFile function to create file
handles that share access to the same file.

Close the app.config file after reading

My "app" is being hijacked by a monitoring service. After it dies, for some reason the app.config file is considered still in use, so I can't make changes.
The only thing I can do is rename the existing file, and save a new file with the old name.
This is not an interactive app, so I want to simply want to use notepad to make changes in the file between runs.
Here is what I would try:
Use Unlocker to figure out what service or process holds a handle to your file and "unlock" it
Try ProcessExplorer. In menu go to Find > Find handle or DLL, search for your .config file and figure out what process is "taking a lock" on the file
Once you figure out what's causing this, check if you can somehow add an exception for your file, so that it's not trying to open this config file - very unlikely but an AV process may do that. Other solutions is to kill a misbehaving 3rd party app and start it once you finished editing config file.
Double check that your app was actually killed and no longer runs. Use process explorer or default task manager (or any other similar tool on non-Windows OS).

Is there a way to monitor the state of a console application?

Is there a way to monitor the state of a console application?
I am trying to build a user interface which shows whether or not a console application is currently running on the server (processing files). If it is running, I would like to show the current state: how many files processed, what file currently being processed, etc.
The only way that I can think of doing this:
Create a text/xml file when application is started
Update text file with information about current state for each object it processes
Delete text file when the application is finished processing
To me, this doesn't seem like a very good or efficient way to do it. Is there a way to detect if the ClickOnce application is running, and perhaps some other way to access the "Messages" or Log of it to show the progress?
Note - I am also looking into using NodeJS to do this, but unsure if it has this capability.
First, you should consider writing this as a Windows service instead of a console application.
That said, scraping a log file that your application is writing is a reasonable approach. Just ensure that it never gets too big.
Alternatively, you could look at using custom performance counters. That would open the door to using System Monitor/perfmon as your monitoring tool, so no need to write any client code.
There are at least two ways to achieve that:
Your console application writes some logs, some state files, during its run, so other processes can read those files and understand what is going on in that console process.
Implement an IPC mechanism. There are different ways to do that. It may help you look in What is the easiest way to do inter process communication in C#?.

Polling directory on File Server

I need to write an application that polls a directory which contains images on a file server and display 4 at a time.
This application will be run up to 50 times across the network at the same time.
I'm trying to think of the best architecture to complete this requirement.
I was working on the idea of opening a file with read/write access and no file share allowed so that if another PC came in to read it it would error and it would have to move on to the next one, the problem is, is that I need to access all 4 images in sequence on the same pc ensuring other pc's dont try to open them. So for example if PC1 tries to open 1.jpg it needs to be able to open 1,2,3,4.jpg. If another PC comes in at the same time to read them I need a way for it to then open 5,6,7,8.jpg and so on and so on.
It seems a simple requirement but a nightmare to try and build successfully.
You're basically dealing with a race condition here, and I don't see a way to handle it from separate instances of your application running on separate machines unless you can guarantee your file naming will always follow a standard naming convention that would allow you to work with the sequence of 4 files using only the name of the first.
The best way to handle this would be using a centralized resource to manage access to your files, either a database as was suggested in a comment or else a service (such as WCF) that would "hand out" each set of 4 files.
What about creating a 1.jpg.lock file? The presence of a the file indicates the images are locked and any other instance of the application should skip that set.

How can I launch a program from memory in C#?

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.

Categories

Resources