Generate an .exe file with embedded settings - c#

I have a window application which performs some tasks, One of which is opening some files and we all know .net provides exe file for the application, which can be used as click to start.
I am calling this application application1.
Now I want to generate one more window application(simple exe), let us call it application2, which will open a form with some options(say the names of the files to be opened by application1) and a generate button.
On clicking the generate button, it should generate the exe file for the application1 with the data passed from application2.
Please suggest how can I do it.
EDIT
I need to generate exe which will be available on different systems which will perform some task on regular intervals. and the interval colud be different for different computers.
so I am asked to generate which will accept the time interval and will generate the exe for that interval

There are a number of ways to consider doing this:
use a reg key with the name of the settings file to read in, and then store the settings you write from app2, for app1 in the file, so app 1 can run it
you call app1 with a parameter with either the name of a file, or commandline parameters, and it updates its own applications settings file.
put the settings in a database, so any copy of app1 anywhere can find it, assuming all users would be able to see the db server
if app1 is always to be running while app2 is you could go with some interprocess communication but probably this is the more complex of the 4
Rather than recompiling an exe, it would make sense to have a config file that goes with.
Failing that, compiling .net is only that, you can have an exe that generates a .cs file (or updates one, and reruns the whole compile and outputs an exe.. take a google, on command line compilation) but I wouldnt be my choice.

I think what your looking for is for application1 to be able to receive command line arguments and application2 to allow you to pick files and run application1 and pass in those arguments.
I don't think its wish to be generating .exe's

Another way, although not that easy, would be to
write application 1 to try and read settings from class that does not exist, say SettingsOverride, by reflection; if not found, fall back to its own hard-coded settings
application 2 uses CodeDOM or similar to create a new assembly that provides a SettingsOverride class with the new saved settings
application 2 uses ILMerge to build the new .exe from application 1 and the settings assembly; the reflection code in application 1 should now pick up the new settings.
It's probably also possible to do this with embedded resources, though I'm not sure how. Finally you could put a string constant in your .exe, say 400 X characters, and then application 2 could scan the file to find that (as Unicode/UTF-16 text) and replace that with a string containing the new settings - but I'm not 100% if you then need to recompute a checksum or similar.

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.

Multiple executable accessing the same folder at the same time

We have a python application that checks a directory(C:\sample\folder) every 5 seconds, there's also this external application(.net app) that puts file into that same directory (C:\sample\folder).
Will there be any conflict when the two application access the same folder at the same time (accidentally)?
Conflicts like :
the external app wont be able to place a file because the python app is currently walking through that same directory?
It should be fine for the external app to create and write to a file. If the Python app is reading a file, the .NET app may not be able to write to it while Python is reading it, without both processes opening the file in a shareable way, however.
Likewise if the Python app is going to start reading the newly-created file, it may either find that it can't do so until the .NET app has finished writing to it, or it may read incomplete data. Again, changes would quite possibly be required to both processes to allow reading at all.
It's worth thoroughly testing all the poosibilities you're concerned about, possibly involving the creation of a "fake" external app which writes to a file very slowly, but opening it in the same way that the real one does.

Run a program from an array of bytes without creating a temporary file . c#

I have many .exe files stored on IIS server (MSSQL) that contain reports and access to the file(s) on the servers . (These files will be change on Sundays .)
After connecting to the SQL Server and choosing an .exe file , I am Downloading(Select in SQL) , Now I have an array of bytes that assigned to a variable .
I cant creating a temporary file like "temp.exe" in an unknown directory because I know there are many ways to understand a new created file directory and ...
It is not secure because my users are professional and if one of them know these ways ...
So , I want know is it possible to run an .exe file from an array of bytes (as default as running from "Windows Explorer") without creating a temporay file ?!
tnx
update : Exe files are .net and Manager will be upload new files or change files .
Be warned that your belief of any extra security is illusory. If the user has access to the machine to read files, they will also be able to read the memory of your process.
However, to answer your question, what you are asking to do is simple enough and described here: Load an EXE File and Run It from Memory.
In essence you do the following:
Pass your byte array to Assembly.Load to create a new Assembly.
Read the entry point of that assembly using the EntryPoint property.
Create an instance using Assembly.CreateInstance, and invoke the method on that instance.
The code looks like this:
Assembly a = Assembly.Load(bytes);
MethodInfo method = a.EntryPoint;
if (method != null)
method.Invoke(a.CreateInstance(method.Name), null);
Doesn't sound safe either way, why are you storing exécutables in a db to begin with? Who uploads them? Wether they're on the filesystem or not they're just as dangerous if malicious.
Are those .net exes? If so you could load the assembly into a child appdomain with security restrictions and i'm pretty sure you can do that without copying to disk.
For regular native exe i don't think it's possible to just launch an exe without a physical file backing it (even in the task manager you can see the path from which a program was launched)
There are two different concerns for security here:
That someone can see the file that you've downloaded from the database.
That executing the file might be a security threat.
For the first concern: Create a directory on the server and restrict access to that directory so that no one but the user account that runs your server program can see/use it. Save the byte array into a temporary file in that directory, execute it, and once the process has completed, delete the temporary file.
For the second concern: You'll need to run that executable in a sandboxed environment. In .NET you can run code in a sandboxed environment by loading the code into a separate AppDomain that you've setup to only have partial trust. How to do that deserves another question on SO though.

How would I find an exe's path just by knowing its name?

How Would I find another exe's path by knowing its name in .net?
Would I add name to the OS environment variable?
Would the other application have to 'register' itself somewhere else?
I need App A to start-up App B and call some WCF services on it.
Thanks!
To answer your question: you cannot know the path simply by knowing the name. An exe can reside anywhere on the file system. There can be multiple instances of it that don't know about each other. Multiple exe files that are completely different can have the same name.
You could take one of several approaches to get round this, depending on the exe you are targetting:
get the user to browse for the exe using a normal file browse dialog
search the file system
see what traces the target exe leaves on the system (filesystem, registry, environmental variables, etc) and use those traces to locate the exe
For either of these options you save the result so you don't have to execute it again when your app is run the next time.
Searching the filesystem could take some time, you are not guaranteed to find the exe (depending upon the user level your app is running as) and you may get false positives, especially if the app is called something dumb like setup.exe.
Getting the user to locate the exe the first time you run is possibly the most reliable way of locating it, but then you have to decide what to do if your app runs but the target exe is no longer at the specified location, or the user has chosen the wrong exe.
If you have some control over App B (i.e. it is your product), then you could consider adding some info to a known spot in the registry when App B gets installed, so that App A can locate it easily. You still need to have a plan B though in case the info is missing.
Reference a path to a shortcut of the exe in the config setting, that way if the exe ever moves around the shortcut will still be up-to-date. Try it, make a shortcut to a exe, then cut and paste the exe somewhere else, then double click the shortcut and you'll see it points to the exe's new location thus will not require changes to app A if the location app B changes.
Really, just make the App B a windows service and start it up when needed.
UPDATE:
Another suggestion would be to create a hard link to the AppB's EXE:
mklink /H AppB-link.exe path_to_actual_exe
Or a symbolic link to whole directory where App B resides:
mklink /D virtual_directory path_to_actual_directory

C# -> Updating an AppSettings.config file on Win7/Vista

I can't see anything on here but I do remember being told that If you want an application to update a config file then it needs to be under ...
**C:\Users\Ibrar Mumtaz\AppData**
Well somewhere there, the reason being is that the user should have permisions to update a config file here and not under the applications install folder. This is the impression that I am under and I'm fairly certain that this is definately the case. As I think I read that on here = p
My question is, is there anybody on here that can shine some light on this as this is the last feature I want to implement before I give my application out to test.
1) First thing is, an installer is needed to set up the folder and then drop my apps config file into it. I already am using the visial studio installer so I have my app packaged up but this point is throwing me off? How do I do this then? I just need someone to show how to do this and I should be O.K reconfiguring my app to look for the new home of the config file.
2) I should be able to work out how to find the folder and locate the config file found within it. As once I know the installer is chucking the config file out into the right folder where the user has permissions then it should be straight forward from there.
Thanks for reading.
UPDATE:
It was pretty straight foward, as the VS Installer has an option to add a special folder so all that was left was to access the folder programmatically and read and write to the config file. ONE PROBLEM? The ConfigurationManager class which I have used to create my config file for my application expects my config file to be local to the application and not miles away in a completey different part of the local FileSystem? Errr help here Plz?
Ibrar
If you are using the VS Settings file to create application setting keys, and have values that the user might want to change in runtime, and save his preferences, just set the scope of those settings to "User" instead of "Application".
That way you will have a setter method for them, and you can edit the Settings.Default instance, and when you are done call the Save() method to persist them to disk.
The file will be saved in the user's "AppData" folder, wherever it is, under some cryptic folder. But you needn't worry about it's location most of the time, since it will be read automatically on the next execute, and persisted to the same location on subsequent runs.
Afaik the installer can be extended with classes that do things.
On INSTALL-action to do could be to
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"My app name");
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
And vice-versa on uninstall.
App.config files are related to where the physical assembly is located I think.
Actually, if your app is running on the user's machine- it will have whatever permissions that user has. So most likely, you can expect to be able to write anywhere on the file system.
However it is possible the user would be running under a restricted acct, and thus not have the permissions. So you could just use the registry to store where your config file is (install folder), then when you try to update it, if it fails for permissions, ask the user to grant it.
Or you could use the Windows standard folders, as you were getting at, because doing so also separates out user data from application data.
Use the Environment.GetFolderPath () method to get the 'special folder' paths in your app.
http://www.programmersheaven.com/2/Les_CSharp_15_p2
http://msdn.microsoft.com/en-us/library/14tx8hby.aspx
If you are talking about application settings found on project Properties -> Settings tab, then there're two different types of settings: user-level and application-level.
If you need to change any settings in run-time, these would be user-level settings (http://msdn.microsoft.com/en-us/library/cftf714c.aspx) and all changes would be buried somewhere in the private folder in your user profile.
If you want to update application-level settings, your best shot would be to do that during software installation. In this case you don't need to look for the configuration file (YourApp.exe.config) anywhere but in the application folder. More likely you would need to create some sort of post-install event handler in your setup package and run some script or another application which would update data in YourApp.exe.config. Everything in the setup package will be executed with elevated priviledges and thus that configuration file would be writeable. BTW, this scenario applies to 2000 and XP, if the user is using limited user account type priviledges.
Because I did not technically find the answer I was looking for, after 6 months I have come back to my application and have managed to produce a solution that does not break my current architecture.
If you are implementing an application to make use of some of the features on offer by the ConfigurationManager then it offers a static method called:
ConfigurationManager.OpenMappedExeConfiguration(); // takes two arguements.
It can be used like this:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = returnUsersAppDataFolderPath();
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
e.g
fileMap.ExeConfigFileName = #"some file path external to your applications install folder."
remember to use '#' symbol in front to allow the compiler to literally treat the string on as is basis.
If the config file can be conveniently locally located then just use the:
ConfigurationManager.OpenExeConfiguration(string exePath)
Above is what you would typically use but for me i needed my config file to located under the users AppData folder so the first option is what I needed. And it does indeed work.
I hope this helps others as it does for me as I want to deploy my application to Win7 and vista environments therefore this question needed asking if I was to stick to using the ConfigurationManager it's a shame the method of choice in the end never really stood out in the first place = ).
If you want to read from your config file then leave a comment and I will show you how I managed to do that also.

Categories