Dealing with files in ASP.NET MVC - c#

Im working on an ASP.NET MVC project that compiles input code to .exe file. Then, my code run this .exe. After success, I just delete that .exe file.
To relaese input code I'm using CSharpCodeProvider class. To run it, I'm using Process class.
Making and deleting exe files seems a little bit tricky to me, because I can't save that files into project directory directly while I'm debugging my program. I need to give special permissions to IIS_USERS. But what to do, when I want to release my project into production? How to deal with filepath? Where to save it?
Now, it looks like this:
string exeName = Path.Combine("C:\\Users\\User\\source\\repos\\proj\\solution\\obj\\Debug", "test.exe");

To deal with paths you should be using Server.MapPath("~") - This returns the physical Path to the root of the web application.
For example if you have a folder called "MyOutput" in the solution (in parallel to the Controller, Views etc. folders) then you can write Server.MapPath("~/MyOutput/"). This will resolve to a physical path like C:\Users\User\source\repos\proj\solution\MyOutput\
This way you do not have to bother about changing paths in local machines or web servers.
Also you should not be putting stuffs in the Obj or Bin folders which are not directly related to the web application.
More samples are available here: Server.MapPath("."), Server.MapPath("~"), Server.MapPath(#"\"), Server.MapPath("/"). What is the difference?

How about asking user where to save it?
You could have a form that ask for this path, username, password etc. Or even in a config <appSettings></appSettings>
Then you can use Impersonate to save it, execute it without any permission issue. You could use this to save it locally or to any network drive

Related

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.

Read SQL query file from project directory

I've put 3 especially large SQL queries within my Visual Studio project, under a folder "Queries" that is in the project directory (not the solution). Is there an eloquent way to access these files? I was hoping that something like #"Queries/firstSqlQuery.sql would work.
Specifying the full path, like with #"C:\\Users\John\Documents\VisualStudio2010\Projects\MySolution\MyProject\Queries\firstSqlQuery.sql
is something I'd really rather not do, since it requires me to go back into code and fix the path, should the application move.
EDIT: For some reason, the page is looking for the files in C:\\Program Files(x86)\Common Files\Microsoft Shared\DevServer\Queries\firstSqlQuery.sql. Why is it looking in this location, when the executable directory is different?
You can do something like this... if it's outside of project. (When I intitially read this-- I misread and thought it was in the solution directory which I was assuming contained the project)--
var pathToBin = Assembly.GetExecutingAssembly().Location;
var directoryInfoOfBin = new DirectoryInfo(pathToBin);
var solutionDirectory = directory.Parent().Parent();
var pathToSolution = solutionDirectory.FullName;
but this is much simpler if it's in the project
System.Web.HttpContext.Current.Server.MapPath("~/Queries/firstSqlQuery");
There are a number of ways to handle this, but there is a fundamental understanding you must gather first. Issuing something like #"Queries/..." isn't, by itself, isn't going to do anything. You need to leverage the System.IO namespace to perform IO operations.
With that part of the foundation, let's lay some more, when you issue a command like this:
File.ReadAllText("firstSqlQuery.sql");
the path that is implied is the Working Directory of the assembly that's executing the code. When debugging an application in Visual Studio, especially and ASP.NET Application, that's the bin directory that resides under the project directory, by default. So, if you did want to access the Queries folder, you would have to do something like this:
File.ReadAllText(#"..\Queries\firstSqlQuery.sql");
so, that's one way of handling it.
Another way of handling it would be to copy the file over into the bin folder every time the project is built by looking at the file properties (e.g. create a Post Build Event), but that's more work than I think you're looking for.
Again, the key here is to understand what directory you're starting in.
Finally, one thing worth noting, if you leverage the directory structure you'll need to ensure that the Queries folder gets deployed to the live site. That probably goes without saying, but I've seen people run into that exact problem before.
You could make sure your query files are copy to the output directory when you do a build and read the files from there without having to set a path.

.net WPF application create a secure folder

I am working on one desktop application which is built by using .net WPF. I have some data inside the application like images,videos..
I want to make this folder secure, so nobody can access the data inside the folder after application installation. Only the application can read the data from that directory.
Even though administrator of that machine can not open that folder to check the content.
Is it possible to have this kind of security inside the WPF application.
Only motive it to keep the sensitive data protected from external copy from the application users.
Thanks,
Vijay
It depends on how you use the resources.
Actually you could encrypt all "protected" files, so that after the installation every one can copy but no one can use them unless your application decrypts the files.
When you encrypt files you should definitively test the performance (decryption takes some time).
Two links showing how you could do it:
What's the easiest way to encrypt a file in c#?
http://lukhezo.com/2011/11/06/encrypting-files-in-net-using-the-advanced-encryption-standard-aes/
Add the file you would like to strongly protect to you solution. Then right click each file, go to properties and set its "build action" to "embedded resource".
And for how to access the resource stream from within the exe for use with in your application, see link below
How to compile all files to one exe?
That way, your private files will not be copied to the installation folder but will instead reside inside your .exe file.
WPF is beside the point. Applications run with the permissions of the users that start them. If an application needs access to files, then the user will also need rights to those files.
In short, the answer is no, you cannot do exactly what you are asking.
The best you will be able to do is make it hard for a user to discover where the assets are coming from, but you will never be able to give access to your application without giving access to the application's user.

Why can't my C# app create files in Windows 7?

I have a C# app that creates a settings file for itself to store the current state of certain visual elements. This app works just fine on any machine that isn't running Windows 7, but on those machines we get an error that the settings file can't be created because the user doesn't have permission. Now, I could fix this issue by going to each computer, logging in as the administrator and giving the user read and write access on the program folder for the application that we've installed, but there has to be a better way.
It seems like in XP, you got write access on the folders you created by default, but that isn't the case anymore. Is there a setting I need in the setup package to make this work?
The point is that you shouldn't be storing settings files in the program folder. Microsoft have advised against this for a long time, but started making things stricter with Vista IIRC.
Use Environment.SpecialFolders.ApplicationData (etc) to find the most appropriate place to put settings. Or use the .NET settings infrastructure which does this automatically for you.
are you trying to create files in the installation folder? you should be using the user data folder for data and not the installation folders. Use the Environment.SpecialFolders.ApplicationData folder to get a folder you can write to.
You're probably running as an administrator on your non-Windows 7 machine which an write anywhere. Be sure to save any per user instance data in their AppData folder (roaming if it should follow them from computer to computer, or local if its a cache or local to taht machine only). If you need to share settings between users, use the C:\ProgramData folder with the appropriate permissions.
A program shouldn't try to store settings in its installation directory.
Be sure to use the SpecialFolders along with Environment.GetFolderPath to get the right locations needed. You should never hard code paths because they can be different between versions AND languages. (I know in the German version of XP it wasn't Program Files but Programme!)
this app works just fine on any machine that isn't running Windows 7
Wrong! It only works on those machines if you run as administrator. I think you'll find your program is broken on Windows XP as well if you try to run it on just about any business computer rather than a home computer.
Instead, this kind of information needs to go in one of the special Application Data folders.
This is a security flaw in your program because your program is writing information to the program directory (which is, and should be, protected.) If it's a situation of correcting the root cause, consider using the SpecialFolder enumeration or the static members on Application like like CommonAppDataPath to write your information to a more appropriate location.
Assuming the typical approach to writing a file via a path, this is a trivial fix and there's no good "expediency" reason to not correct the root cause. If you're not sure about how to manipulate the path, consider using Path.Combine(). It does it for you.
In general, you shouldn't be writing program data to any folder underneath Program Files (even if you created the folder). You should use the Environment.GetFolderPath(...) to figure out where to put your application specific data. You can pass in one of many enums defined here -- you probably want Environtment.SpecialFolder.CommonApplicationData
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
I do not see how any of this is an actaul answer. I need to be able to write a report and have it saved the users documents folder the same folder I used to read the xml files I am writing the report from.

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