How to change active file in external process? - c#

What I'm trying to do is use SolidWorks' eDrawings (as an example) to open a specified .dwg file that the user selects from a list my application generates.
I am able to do this without issue, but what I'd like to do at this point is, if the eDrawings process is already running, change the .dwg it is displaying to the new one the user has selected.
I already have the Process object for the eDrawings application, and I have used process.CloseMainWindow() successfully on it, so I know my app is targeting the correct process.
I just need to know how to instruct it to change files. Is this going to be something specific to eDrawings (and/or unavailable from the .NET framework itself) ?
Maybe something like
Process myProcess = Process.GetProcessesByName("eDrawings")[0];
myProcess.CurrentFile = myNewFile;
Can this be done?
EDIT:
For emphasis on the solution I seek, I want the eDrawings program to load the new .dwg file without closing and opening a new instance of itself.
The point of trying to do this is to get around the excessive load times every time the application opens.

If I understood your question properly and you try to let other processes to access your main application process you might want to read about Interop Marshaling: http://msdn.microsoft.com/en-us/library/eaw10et3.aspx

Related

How to programmatically determine which process created a file in .net?

There are several threads on SO that describe how to check which application creates a file with tools like Sysinternals process monitor. Is something like this possible programmatically from .net?
Background: My program has to remote-control a proprietary third party application using its automation interface, and one of the functions I need from this application has a bug where it creates a bunch of temporary files in %TEMP% that are called tmpXXXX.tmp (the same as .net's Path.GetTempFileName() does) but does not delete them. This causes the C drive to become full over time, eventually failing the application. I already filed a bug to the manufacturer, but we need a temporary workaround for the time being, so I thought of putting a FileSystemWatcher on %TEMP% that watches tmp*.tmp, collects these files, and after the operation on the third-party application finishes, deletes them. But this is risky as another application might also write files with the same file name pattern to %TEMP% so I only want to delete those created by NastyBuggyThirdPartyApplication.exe.
Is this anyhow possible?
This kind of things is possible, but maybe a bit tricky.
To know who created the file, look at the user that owns it. Therefore you might need to create a specific user, and that application will run under this specific user. In order to do that, you need to create a small application that will start your buggy app by impersonating another user, so anything done within the app will be under this user so as file creating...
I don't know how to monitor and get triggered when a file is created, but nothing can prevent you from setting a timer that wakes up every five or ten minutes, then checks if any file in the directory is owned by the application user and closed, so it deletes it.
Maybe if they react fast for this bug fixing, you won't need your app very long time. So another solution, if possible might just to change the Temp folder into another drive, which has lots of space...
One solution is that you use a FileWatcher to automatically delete all the files but before deleting you should check if the file is not currently locked or used by other process, for example the Sysinternal Suite has a tool called handle.exe that can do this. Use it from the command line:
handle.exe -a
You can invoke this from a c# program (there might be some performance issues though)
So what you would do is when a file is created you verify if it is in use or locked (for example u can use the code provided in Is there a way to check if a file is in use?) and then delete it.
Most of the time when an app is using a temp file it will lock it to prevent just what you fear, that you might delete files from other processes.
As far as I can tell there is no sure way to identify which process created a specific file.

C# Change File Location For Next Time Program Runs

I am relatively new to C#, however I do have some basic knowledge of code from courses in high school and university. However, there is one thing I have not been able to figure out over the years. I am currently making a Form Application for a database system that stores information in a List using Visual Studios 2010.
On my main form; when the save button is pressed, the information is then serialized into an XML file. When the information is loaded, the information is then deserialized and put into the List for use in the code. All this is working correctly.
This process of saving and loading is done based on a string which contains the file path. This string is the location of a folder on my desktop (I put it there for easy access), and I am able to change the string in the code to basically move where the information is stored.
However, I have a separate "Admin" form which is able to change this file path string. When the user clicks the button to change the file path, I get the input from a text box, check its formatting, move the current file to the new location and update the location for the save method so changes can be saved before the program is closed. From there, the program reacts the same way as if I had changed the string from inside the code.
The problem occurs when I close the program. I do not know how to tell the program when it runs again that the location has been changed from the default and look for the file in the new location. The program reacts just like the file was missing (like it should) when it looks in the default location.
So basically, how do I tell the program that the save location was changed from when it was last run so it knows to load the info from a new location?
I have tried looking for an answer since high school (about 2 years ago) and have not found a solution. As a result I usually just keep the save location as the default (which I set it to) and don't try to change it. But this time, its important that the save location can be customized. My experience with Visual Studios is limited, as everything I know is from messing around with the program and looking up stuff when needed.
If needed, I can post snippets of my code. Thank you in advance!
It seems like what you really want is to save some user-defined settings for recall at run-time. Here is a MSDN link describing some basic conventions for storing / retrieving these settings.
https://msdn.microsoft.com/en-us/library/bb397750(v=vs.110).aspx
A *.config file would suffice (depending on the scale of the application).
Otherwise, you may want to go down the route of storing these settings in a database (if the scale is rather large, or if user-authentication is required for the application).
Here is another previous question dealing with this same subject (regarding App.config files):
What is App.config in C#.NET? How to use it?
I recommend using a config file where the .exe is, and write the location there, then read it in on program startup.
In particular .net provides this class which can manage your config file for you (assuming you have an app.config in your solution, otherwise create one)
https://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.appsettings(v=vs.110).aspx

There is a way to delete an file that is being executed without kill it?

I have a question that I believe that is complex. I have an application that I execute under my Windows and it takes a long time to finish. I want to keep it running (normally), however I want to kill the file on disk - but obviously it's not possible because it's locked / in-use. I need a way to disassociate it from the running process to kill it and at the same time keep the file running. Any example of code or tool is very welcome.
Well, workarounds are welcome, for example, if there is a way to spawn it from a process, key the master and migrate the child to kill the app, or any other idea that works is welcome - even the ugly ones. :)
Thanks.
A couple of suggestions (completely stolen) from this questions answers:
You could use the MoveFileEx api function to mark the file for deletion upon next reboot.
You can inject a dll to close the handle yourself:
The typical method is as follows. You've said you want to do this in C# so here goes...
If you don't know which process has the file locked, you'll need to examine each process's handle list, and query each handle to determine if it identifies the locked file. Doing this in C# will likely require P/Invoke or an intermediary C++/CLI to call the native APIs you'll need.
Once you've figured out which process(es) have the file locked, you'll need to safely inject a small native DLL into the process (you can also inject a managed DLL, but this is messier, as you then have to start or attach to the .NET runtime).
That bootstrap DLL then closes the handle using CloseHandle etc.
Essentially: the way to unlock a "locked" file is to inject a DLL into the offending process's address space and close it yourself. You can do this using native or managed code. No matter what, you're going to need a small amount of native code or at least P/Invoke into the same.
Helpful links:
http://www.codeproject.com/KB/threads/winspy.aspx
http://damianblog.com/2008/07/02/net-code-injection/
That is a matter the application you want to kill has to handle. It shouldn't keep files open during a long running process. If the application doesn't close the file, killing it will lead to exception in that application.
Not sure if this will work on every Windows version, but here it is:
Rename process executable "foo.exe" to "foo.old"
Put new "foo.exe" to correct place
Send message to process, so it will execute new "foo.exe" image and terminate himself.
On start, remove "foo.old" file in program directory.
Update: oops, looks like you do not want to put new image, just remove old one. Then MoveFileEx is only "legal" option.

Rename a running executable (exe) file [duplicate]

This question already has answers here:
Why does rename a loaded .net assembly work?
(3 answers)
Closed 5 years ago.
We are trying to push updates to multiple servers at once and my manager has found that it is possible to rename running .exe file. Using that knowledge he wants to rename a running exe and copy over a new version of said exe such that anyone running their in memory copy of foo.exe are fine and anybody who opens a shortcut pointing to foo.exe will get a new copy with updates applied.
I guess I need to clarify, He doesn't expect the old copy to magically update, he just expects them to keep running the old copy until they open the exe again, in which case it will then open the new one that has the name of the old one.
It sometimes throws an exception that the file is in use on his program but if he tries renaming it in a loop it will eventually succeed. On my machine I have yet to be able to get it to work even in a loop.
My first and main question is this: Is it ever acceptable to do this. Should renaming a running executable ever be a valid scenario?
Secondly, if it is a valid scenario then how could one reliably do this? Our current thoughts are try a bunch of times using File.Move (C#) to do a rename and if it doesn't work then write out to an error log so it can be handled manually.
An airplane mechanic and a surgeon meet in a bar. The mechanic says "you know, we have basically the same job. We take broken stuff out and put new, better parts in." The surgeon says "yeah, but you don't have to keep the plane flying as you're making the repairs!"
Trying to update an application by moving files while the application is running seems about as dangerous as trying to fix an airplane in flight. Possible? Sure. Greatly increased risk of catestrophic crash? Yep.
If the application you are updating is a managed application, consider using ClickOnce Deployment. That way, the next time someone runs the application, if there is a new version available it will be copied down and installed automatically. That's much more safe and pleasant than trying to mess with an application while its still running.
No, this is not acceptable. Do not do this. This is not a valid deployment mechanism. This should have been yours or his first clue:
It sometimes throws an exception that the file is in use on his program but if he tries renaming it in a loop it will eventually succeed.
And it won't work, anyway. His theory is quite wrong:
Using that knowledge he wants to rename a running exe and copy over a new version of said exe such that anyone running their in memory copy of foo.exe are fine and anybody who opens a shortcut pointing to foo.exe will get a new copy with updates applied.
Specifically, the copy in memory will not be automatically replaced with the new executable just because it has the same name. The reason that you're allowed to rename the executable in the first place is because the operating system is not using the file name to find the application. The original executable will still be loaded, and it will remain loaded until you explicitly unload it and load the new, modified executable.
Notice how even modern web browsers like Chrome and Firefox with their super fancy automatic, in the background, no one ever notices that they exist, updaters still have to close and relaunch the application in order to apply the updates.
Don't worry about shooting the messenger here. It's more likely that your customers and your tech support department will shoot you first.
See number 1.
In our organization, we solved the problem of Updates by having two release folders say EXE_A and EXE_B. We also have a release folder called EXE which only has links ALL of which points to either to EXE_A or EXE_B from which the user runs the applications.
When we publish a new version of the program, we publish it to the folder that is not referenced in the links and then update the links (EXE). In this way, you do not get into exceptions that users are holding the application / assemblies. Also if a user wants to run the updated version, all he need to do is close / re-execute the link in EXE folder.
If you use Windows Vista/Server2k8 or newer you could use mklink to create a symbolic link to the folder containing your application and start the application out of the "symblic linked folder" and then at the update create a new folder, e.g. "AppV2" and change the SymLink to that folder, so the next time the user restarts the application he starts it out of the new folder without noticing.
Renaming open files is ALWAYS a bad choice!
But in general I would think of a better deployment strategy anyway, because if you need to use such "hacks" it is always a messy situation. I don't know your application, but maybee ClickOnce would be a point to start, because you can configure it to check for updates on every start...

c# Programme Error

Unable to copy file "obj\Debug\FootballLeague.exe" to "bin\Debug\FootballLeague.exe". The process cannot access the file 'bin\Debug\FootballLeague.exe' because it is being used by another process.
I got this problem and I couldnt find any another process.Other c# programmes are working properly.I changed the place which I haved saved first time, but I couldnt get any clue to find the error.
Chances are the other process is FootballLeague.exe - are you sure you aren't still running it?
Another alternative is to use Process Explorer to find out what's got a handle on the file.
If your FootballLeague.exe has been launched and is still running, it is the process that is locking the file.
Do you have a virus scanner turned on? They tend to open files for exclusive access at just the wrong time. I would advise that you turn off real-time scanning in your project directory at a minimum.
Other than that, you'll want to use something like Process Explorer to find out who actually has the file open.

Categories