Got an annoying problem here. I've got an NHibernate/Forms application I'm working through SVN. I made some of my own controls, but when I drag and drop those (or view some form editors where I have already dragged and dropped) onto some of my other controls, Visual studio decides it needs to execute some of the code I wrote, including the part that looks for hibernate.cfg.xml.
I have no idea why this is, but (sometimes!) when it executes the code during my form load or drag and drop it switches the current directory to C:\program files\vs 9.0\common7\ide, and then nhibernate throws an exception that it can't find hibernate.cfg.xml, because I'm searching for that in a relative path.
Now, I don't want to hard code the location of hibernate.cfg.xml, or just copy hibernate.cfg.xml to the ide directory (which will work). I want a solution that gets the solutions directory while the current directory is common7\ide. Something that will let someone view my forms in the designer on a fresh checkout to an arbitrary directory on an arbitrary machine. And no, I'm not about to load the controls in code. I have so many controls within controls that it is a nightmare to line everything up without it.
I tried a pre build event that made a file that has the solution directory in it, but of course how can I find that from common7\ide? All the projects files need to be in the solution directory because of svn.
Thanks for your help guys, I've already spent a few hours fiddling with this in vain.
UPDATE: I set hibernate.cfg as an embedded resource. For each configuration I just simply make a new build configuration, debug, release, XYZ. In most cases I'd recommend embedding any files you depend on to run the program. It makes it much simpler to build an installer.
A solution folder is a container for one or more related projects. You can create many folders within a Visual Studio solution, including nested folders. They appear in the Solution Explorer as expandable and collapsible sections.
Working Directory is the location which Specifies the working directory of the program being debugged. It is the default place in which a program is looking up it's files. Normally the working directory is the directory the application is launched from \bin\debug by default.
Open Project -> Properties -> Configuration Properties -> Debugging . The working directory entry is $(ProjectDir) by default. To change it to the place the execute resides change the value to $(SolutionDir)$(Configuration)\ .
This is probably coming a little bit late, but I've found a solution at http://www.tek-tips.com/viewthread.cfm?qid=1226891&page=164. Since I am using Visual Studio 2010, I made a few minor changes. You have to reference the EnvDTE and EnvDTE100 (EnvDTE90 for VS2008),
string solutionDirectory = ((EnvDTE.DTE)System.Runtime
.InteropServices
.Marshal
.GetActiveObject("VisualStudio.DTE.10.0"))
.Solution
.FullName;
solutionDirectory = System.IO.Path.GetDirectoryName(solutionDirectory);
Of course I used VisualStudio.DTE.10.0, you should probably use VisualStudio.DTE.9.0.
Good luck!
I've finally figured this one out. This will work for any Visual Studio version, does not rely on EnvDTE, and solves the original problem presented here.
In your project settings, under "Build Events", add the following "Pre-build event command line":
echo $(SolutionDir) > ..\..\solutionpath.txt
Build the project once. The file will be created in your project root.
In solution explorer, click "Show All Files" and "Refresh"
Add solutionpath.txt to your solution
Right click solutionpath.txt, click properties. Change your build action to "Embedded Resource"
Use the following code to get your solution path.
string assemblyname = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
string path = "";
using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(assemblyname + ".solutionpath.txt"))
{
using (var sr = new StreamReader(stream))
{
path = sr.ReadToEnd().Trim();
}
}
Because this is a pre-build event, the file does not need to exist before the build is started, so it is compatible with source-control and doesn't have any obvious issues.
Update: Unfortunately, i don't know how of a way to get your solution folder at design time. So, technically, I am not answering your question, just offering a potential workaround.
You can check if your control is in DesignMode
and if it is, you can use Assembly.GetExecutingAssembly()
to get the Assembly
for your control and determine the location it was loaded from.
Note that there are some caveats with the DesignTime
property value, namely if your designing your control or if you are designing a Form that contains your control, it'll return properly true, but if you are designing a form that contains a control that contains your control, it'll retun false.
You might want to skip the whole DesignTime check because of this and always look for the NHibernate config in the base path of your assembly, if your standard way to find that config file fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With