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.
Related
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
This sounded like a trivial question initially but I did not come across any solid/best practice solution on how to do this so I am asking the question here. Now, let's imagine that we have to work with couple of ".txt" files in our code which is in a class library.
Now, I think there are 3 major ways to handle this:
Just put everything in your Bin/Debug/Resources folder of the calling application and in your code use "Resources\*.txt". I think this is the simplest and most unobtrusive way to handle this. However, there are many trivial problems with it:
When you check in the source control would not check-in the files inside the Bin/Debug folder
So in this case, probably adding the folder one level above and then writting post-build scripts is the most efficient option I guess?
Add resources folder on the same level as Bin folder. That way we can successfully manage it using the source control. however now when we need to reference it through our code it becomes tricky
We can reference this files assuming that the Binary folder's structure is like Bin/Debug and reference to the Resources folder like ..\..\Resources
But this structure is not always guaranteed what if the binary folder structure is like Bin/ (without any debug folder in it) then ../../Resources is going to fail
Add all the txt files as .RESX files. But I am not sure if it is the practice around everywhere and the most popular way to store resources.
-Also, the code that we have to write to access the resources files sounds like cumbersome as oppose to just picking up the file from windows file system.
Probably I am missing something trivial but I was just curious and was thinking that it should be much more simpler than this. Any suggestions?
Create a different project in the solution called Myproject.Resources.
Next install Microsoft MAT and manage your translations with MAT: https://developer.microsoft.com/en-us/windows/develop/multilingual-app-toolkit
You manage your translations with MAT and the .resx files are kept up-to-date. ;-)
I have an app that has search functionality. The search algorithm is compiled to a separate dll. In the C# code for the search algorithm, I am using strings held in a settings file to point to the directory where the search index resides. But once the search code is compiled, the settings file is somehow incorporated in the dll. I want to have multiple versions of this code running on my server with each pointing to a different location for the index. And I want the operator to change a file to have each version point to something else as they find necessary. Both config files and settings files end up getting incorporated in the dll. How do I then accomplish this? What is the right industry standard way of doing this?
It's strange that the settings file is compiled... are you sure about that? Setting, config and resx files should be copied to the output directory, it's even a property you can modify on solution explorer. Then you should get it's values by doing
System.Configuration.ConfigurationManager.AppSettings.Get("YourKey")
But I think this won't know about user changes until app is restarted. If you want settings to be dynamic you should either store them on a database, or on a file that you open, read and close every time you need it.
Hope this helped!
So I recently updated my application to support a new feature. In the past if the configuration file was deleted by the user it wasn't a big deal. This new feature requires it to exist, and one of the requirements is that, the file exists in the application's installation directory.
I have notice when the file is deleted ( depending on variables I have not figured out ) I get a .NET notification that the configuration file is missing or corrupt. Currently my program then crashes ( I still have to figure out how to duplicate this behavior ) which is the reason for this question.
I am familar with ConfigurationManager. I am having trouble writting the file once the default values are loaded. Forcing a Save for some reason does not seem to recreate the file, at least not in the installation directory, which is a requirement.
I am looking for guidence on how to handle this corner case in an elegant manner. I would post code, honestly its just all failed attempts, which while my attempts do generate a file the contents are not the settings I am looking for.
I am willing to post anything that might be able to help.
Stop using the built-in config support and just use write/read to a file called something.exe.config using the standard XML classes and if that gets deleted, just re-create it from values hard-coded in the executable.
The config file support is supposed to make things easier, if you need to do stuff where it makes things difficult, don't use it.
Something like
var wcfm = new WebConfigurationFileMap();
Configuration newConfig = WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
newConfig.Save();
doesn't work?
You dont. Under normal conditions the program can not write into it's install directory - this is a standard windows security issue and the reason why app application data should reside ni external (from the exe's point) driectories.
If an admin deletes the config file, crash, ask for reinstall. There is nothing you can RELIABLY do, as you can not assume you can write into the folder at runtime. A message followed by an event log entry is the best approach here. Users are not supposed to delete parts of the application.
I am by no means a programmer but currently am wondering if an application creates a temp file that windows names. For example the file it creates is tmp001, is there a way i can take that name tmp001 and ask windows to give me the next temp file it would create before it creates it.
Thanks,
Mike
There is no direct means to get to know the next temporary filename to be created.
For example, programmers use the System.IO.Path.GetTempFileName method, but one can add application-specific prefixes or suffixes in order to make it easier for the application to find its newly created files.
One can even choose to save this temporary file elsewhere than the system Temp folder.
You would need to define a "temp file" much more explicitly in order to answer this question with a "Yes". The problem is that a "temp file" is just something not meant to be kept. It could exist anywhere on the system and be created by a user, application, or service. This would make it nearly (or actually) impossible to answer your question with a "Yes".
If you constrain the definition of a temp file to just the files in the official temp folder (or a subfolder), you still have a problem if you're trying to catch names not generated by windows. Any app could produce a particularly named temp file in that folder, without Windows caring.
If you further constrain the definition to be only those files named by Windows, you might be able to get somewhere. But, does that really meet your needs?
After all of that, maybe it would be better to describe the problem you're trying to solve. There may be a much better (workable) solution that would address the issue.
Typically applications use the Win32 API GetTempFileName to get the temporary directory.
The process of how the temp file is generated is described there.
I'm not sure why you want this info, but perhaps you could for example register for directory changes via a Win32 API like ReadDirectoryChangesW or by using a mini filter driver.
This kind of code just cannot work reliably on a multi-tasking operating system. Another thread in another process might pre-empt yours and claim the file name you are hoping to create.
This is otherwise easy enough to work around, just name your own files instead of relying on Windows doing it for you. Do so in the AppData folder so you'll minimize the risk of another process messing it up.