Access project files from class in separate folder - c#

Screenshots below are from the Solution Explorer Pane:
I have a class in Folder DataAccess that needs to access a resource in Folder data. I get the following error message.
System.IO.IOException: Cannot locate resource 'data/danio_rerio.xml'.
Does not Work If:
It works if:
Folder data is a child folder within Folder DataAccess. Is it possible for me to use the following syntax:
foldername/somefile.someextension
to access resources within the project that are in seperate folders?
Edit: I do not want to hard code locations to my directories.

When you run your application, the running directory becomes your "active directory"
Suppose you have
c:\myproject\bin\debug\myapp.exe
When you run the application you try to search
c:\myproject\bin\debug\foldername\somefile.someextension
what you actually want could be close to
c:\myproject\data\daniorenio.xml
so you'll want to search the following directory
c:\myproject\bin\debug\..\..\data\daniorenio.xml
The .. operator tells that you want to go back in the directory hierarchy
However this is assuming your binary will be in a lower branch than your ressource. What I actually do is copy everything I absolutely need for runtime inside a special directory such as
c:\myproject\RuntimeRequired
This way I can issue a post build event like this (In Project/Properties/Build-Events/Post-Build)
copy /Y "$(ProjectDir)RuntimeRequired*" "$(OutDir)"

I found the answer myself. Should have searched more before offering a bounty -_-
Pack URIs in WPF [Source]

Related

How to copy built assemblies into a project resource folder?

In the Resources folder of my project, I have many different DLLs from other assemblies in my solution. These DLLs are used as embedded resources so I can have a single EXE without having to have local copies of all the DLLs. What I want to be able to do is have them updated every time I build my entire solution. So for example, if I have AssemblyOne/bin/x86/Debug/Foo.dll, I want the DLL to always copy over to LocalAssembly/Resources/Foo.dll whenever I build the project.
Is there an easy way to do this? I was looking at the post-build-event macros, but none of them would be able to directly reference my "LocalAssembly", which is not the Solution Directory. Also, I'm not sure how I would go about writing a new custom post-build command in a way that the newly copied DLLs would not be an absolute reference to my local machine. Thanks! Please comment for more information and I will edit the question.
You need not access only your solution folder in post build events. The post build scripts run with whatever permissions the compiler had when it ran. Since in Visual Studio things frequently run with Administrator permissions, chances are great you have access to your entire file system. As a result, if you are wanting to copy resources around, you merely need to presume that you are starting the xcopy call in the build destination directory. From there, you can navigate around with normal paths. So if, for example, you needed go up three levels and then into the directory LocalAssemblies, your copy command would look like xcopy Foo.dll ../../../LocalAssemblies.

Where do I put a folder that is used in my C# application?

I'm planning on my C# application having a folder called Data that is reused whenever the program is launched. I put it in the root of my Visual Studio solution which causes it to be where you see below
MyProject (File folder)
bin (File folder)
Debug (File folder)
MyProject (Application)
.
.
Data
obj
.
.
.
.
after the project is built ... but I'm guessing I'd want it where the actual application is, right? Or is it proper for me to instead have a "Create if doesn't exists" for that folder in my application? Sorry if this is considered a subjective question.
1) you may check it at the start of the program if it doesn't exist then you may create it.
Right click on your SOlution in visual studio>> Add new project>> Under other project types>> Choose>> Setup and deployment >> Visual Studio installer >> Set up project.
Setup projects are important in many cases, when you need to make any changes for first time installment or need to modify registry, need to copy some data folder or other settings for the first time.
2) Create a setup project and in your setup project you may create that data folder, which will be created when user will install the application.
I would prefer to use both option to avoid any issue in future.
From what it looks like in your example the data folder you created in your application/solution explorer. So far so good but it wont ever be created inside your project.
You have 2 options if you want it to be in the same directory as your application.
You create a .txt file or whatever you want to put into it later on in the solution explorer and say "copy always" in the properties
Is you create your folder manually inside your program. The base location of your program is usually AppDomain.CurrentDomain.BaseDirectory. Thus you could use Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + folderName).
For 2 this could be done on each run on the program (if the directory does not exist yet OR on setup of the program if you have a special setup routine).
As far as I'm aware all of these variants are legit and are dependent on your exact use case and personal taste.
I'm guessing I'd want it where the actual application is, right?
NO! Let's say you eventually bundle this program into an installer the puts it in it's own Program Files folder. Standard Users do not have write access to anything under the Program Files folder!. You just forced your program to require Administrator rights every time it runs.
Instead, you need to put your data folder in the Application Data special folder:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

Windows Form Localization

I'm trying to get localization to work in my application. I can follow the typical example online and get it to work in a sample project. (ie. setting the Localizable property and the cultures).
When I try to use it in my application, it always uses the default resource file no matter what language I choose.
EDIT: If I go to the properties of my startup project, select Debug, and set the Start Action to Start Project, it will work. If I run the executable that gets created when building by selecting it in "Start external program", it will not work. Any idea why?
EDIT: When I use the Start External Program, the executable I am pointing to is not pointing to the bin/Debug folder of the project. I have a post build event to copy it elsewhere and am pointing to that. Because of this, maybe it is not able to see the reference files that are in the Debug folder?
When you localize a form, it creates a folder per language in the build's output path that holds a resource file projectname.resources.dll.
I have a post build command that puts our .dlls elsewhere. I needed to change the command to also push out the resource files so that they were in the same directory. Once I did this, I was able to get it to work.

Visual Studio Moving a Content File on Publish

I'm developing a Web application that uses a couple XML files to store data. I have their Build Action set to Content, and on install the files are copied successfully to the Applications Virtual Directory:
C:\inetpub\wwwroot\ApplicationName\
The problem I'm having is that writing to these XML files (in order to save settings and things like that) causes a lot of write permissions issues. Therefore to get around it, I'm trying to copy these files from the virtual directory they're installed to to a new directory under the C drive, using the following PostBuildEvent in the Web Deployment Project:
xcopy "$(TargetDir)*.xml" "C:\CompanyName\ApplicationName\" /y
However, this does nothing. I'm not sure if this is because PostBuildEvents in the installer are not actually fired on install, but only on building the installer, or if TargetDir represents the bin directory:
C:\inetpub\wwwroot\ApplicationName\bin\
instead of the root application virtual directory:
C:\inetpub\wwwroot\ApplicationName\
Does anyone have any ideas? Has anyone dealt with this sort of thing before? I'm really stumped on this one.
Update:
I included a PostBuildEvent that should give full permissions to all users:
icacls "$(TargetDir)" /grant Users:F
But it doesn't seem to have resolved the problem.
I'm also unsure where exactly $(TargetDir) if pointing to, if it would be ..\ApplicationName\ or ..\ApplicationName\bin\
All you have to do is give full permissions to the user under whose context the Web Application Pool runs.
You can find this user by starting IIS manager and look at the Application Pools and Identity column
Something like
cacls C:\inetpub\wwwroot\ApplicationName /G Users:F
will give all permissions to this subdirectory to all users on the computer, If you are running under ApplicationPoolIndentity refer here
Turns out there's a much easier way to do what I was trying to do.
Instead of using PostBuildEvents to create a new directory structure and move files there, I added the new directory structure into
InstallerProject > View > File System
after which I located the Content Files from SomeProject entry in my installer project, and changed the Folder value to the newly specified directory structure, in this case
C:\CompanyName\ApplicationName\
This seems to work fine, I'm now able to access these files freely as I originally intended.

Relative paths in C#

I need some help with paths please!
Basically I have a project with the following folder structure:
Project (root directory which contains the .sln file etc.)
Project/MyProj (contains the code)
Project/MyProjTest (the test folder)
Project/TestResults
Now with this Project I need to have a common folder where I can stick a bunch of files for use with the Application without having to copy the files to multiple locations etc. What is the best way to do this? Ideally I would like to have the folder as Project/ResourcesFolder, so that both the Code folder and Test folder can access it. Now if this is the case how do I call this folder from within C#? I've tried Application.StartupPath, Environment.GetCurrentDirectory but they both just return the CURRENT folder which is not what I want.
Thanks in advance.
You can add a solution folder to your solution and place common files in it.
You'll have to copy the files, you'll want your program to operate the same way after it is deployed. The simplest way to do so is by adding them to your project. In the Properties window, set Build Action = None, Copy to Output Directory = Copy if Newer. The latter setting ensures that you don't waste time copying the files over and over again.
This ensures that the files will be present in the same directory as your EXE. Both when you debug and after you deploy it. Simply use Application.StartupPath to locate them. Creating the Setup project for the app is now very simple as well.
Note that if the files are small you really want to embed them as resources.
.. goes one directory up. That is, from Project/MyProjTest you could access Project/MyProj via ../MyProj.
Use Server.MapPath("~") to get to the root folder of your application. From there you can get to wherever you need.

Categories