|DataDirectory| in Project properties > Settings - c#

The connection string setting is below:
Name:
dbPersonConnectionString
Type:
Connection string
Scope:
Application
Value:
Data Source=|DataDirectory|\dbPerson.sdf
When I install & run the application, it looks for DB in C:\MyApp\Data\ folder. It should be C:\MyApp without additional \Data folder.
Should I simply create Data folder in my project and move DB files under that folder or I simply adjust |DataDirectory| -and how-?
EDIT:
string executable = System.Reflection.Assembly.GetExecutingAssembly().Location;
string path = (System.IO.Path.GetDirectoryName(executable));
AppDomain.CurrentDomain.SetData("DataDirectory",path);

This has been asked before. This MSDN post gives a good overview.
It should indeed default to your binaries folder, you can change it with AppDomain.SetData() . If you change it, better do it early.

AppDomain.CurrentDomain.SetData("DataDirectory", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
This should work always because Directory.GetCurrentDirectory() may return other directory than the executable one

This one solved my problem
AppDomain.CurrentDomain.SetData("DataDirectory", Directory.GetCurrentDirectory());

Related

Set the connection string to the path of the database dynamically [duplicate]

I am using SQL Express databases as part of a unit test project in c#. My databases is located here:
./Databases/MyUnitTestDB.mdf
I would like to use a relative path or variable in the app.config rather than having my connection string defined as:
AttachDbFilename=C:\blah\blah\blah\yea\yea\yea\MyApplication\Databases\MyUnitTestDB.mdf
I have seen the use of |DataDirectory| but am I correct in thinking this is only applicable to web applications?
I want to control this in the application configuration file, as in production the application uses a hosted sql database.
Thanks everyone, I used a combination of your responses.
In my app.config file my connection string is defined as follows
<add name="MyConnectionString"
connectionString="Server=.\SQLExpress;AttachDbFilename=|DataDirectory|\MyDatabase.mdf;Database=MyDatabaseForTesting;Trusted_Connection=Yes;" />
In my unit test class I set the DataDirectory property using the following
[TestInitialize]
public void TestInitialize()
{
AppDomain.CurrentDomain.SetData("DataDirectory", System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Databases"));
// rest of initialize implementation ...
}
Yes, |DataDirectory| Web application to select the App_Data directory of the web application.
In a not web application, depending on .NET Framework, it could be used and also changed using AppDomain.SetData
But you have other two posiblities to create the connection:
1.- Use a relative path:
String con ="... AttachDbFilename=Databases\MyUnitTestDB.mdf ... ";
2.- get the application path and add to the String.
In c# Windows Application you can use Application.StartupPath
String con= " ... AttachDbFilename=" + Application.StartupPath + "\Databases\MyUnitTestDB.mdf ... ";
Depending on the applicaiton type or launch mode you got different properties. Ex:
Application.StartupPath -- The start path of the exe application that starts the application
Application.ExecutablePath -- the start path an name of the exe application that stats the application
But to use Application you need to include System.Windows.Forms that is not included for example into console applications.
System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) -- This gets the path from the current assembly "dll,exe,..." Is not affected by application type, path changes,... Always return the directory when the Assemby resides.
Environment.CurrentDirectory -- the current directory. This can be changed for example if you navigate into folders.
You can find more about the different connection string options here
http://www.connectionstrings.com/sql-server-2005
I have spent a whole day googling to work this through and finally have a clue from this
Here is my solution:
1. Use |DataDirectory| in connection string
<add name="NorthwindConnectionString" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDbFilename=|DataDirectory|\Northwind.mdf;User Instance=True" providerName="System.Data.SqlClient" />
2.Set DataDirectory in ClassInitialize
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
int index = baseDir.IndexOf("TestResults");
string dataDir = baseDir.Substring(0, index) + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
}
I'm building a simple Windows Forms App with VS2010 with C#3.0. Also using SQL Express 2008 RC2.
I am able to use: |DataDirectory|MyDb.mdf in the connection string alone without changing anything else. The |DataDirectory| points to the location of my .exe file.
I will think that this would be the first thing all of you would try, so that is why I'm specifying my VS and SQL version. Or maybe it is new to C#3.0.
My complete Connection String:
"Server=.\SQLExpress;AttachDbFilename=|DataDirectory|App_Data\ThumbsUpPlayer.mdf;Database=ThumbsUpPlayer;Trusted_Connection=Yes;"
Note that I have added a "App_Data" folder to my application, because I'm used to the Db in that folder, the folder is not recognised by VS.
I don't have Visual Studio here, but what about:
using System.IO;
using System.Windows.Forms;
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
AttachDBFilme = appPath + "\\MyUnitTestDB.mdf"
I did the following. Hopefully it helps someone.
AppDomain.CurrentDomain.SetData("DataDirectory", System.IO.Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + "../../App_Data"));
Dynamic Path in SQL Server Connection
SqlConnection con="Server=.\SQLExpress;AttachDbFilename=|DataDirectory|\MyDatabase.mdf;Database=MyDatabaseForTesting;Trusted_Connection=Yes;" ;

DbMigration.SqlFile difference in base directory

We are using the new DbMigration.SqlFile method in EF Migrations 6.1.2 to run a migration script in our migration. According to the documentation, the file has to be relative to the current AppDomain BaseDirectory. We have included these files in the project, and set them to copy to output directory.
Locally this all runs fine. They get output to the bin directory, and run fine.
When deploying the software to a server running IIS however, the migration fails, because it suddenly expects the files to be relative to the root. When I copy them there, the migration works.
How can I use DbMigration.SqlFile so it runs correctly both locally and on the server?
The SqlFile method uses the CurrentDomain.BaseDirectory if a relative path is given. A workaround is to map the path yourself and give an absolute path to the method. A solution would look like this:
var sqlFile = "MigrationScripts/script1.sql";
var filePath = Path.Combine(GetBasePath(), sqlFile);
SqlFile(filePath);
public static string GetBasePath()
{
if(System.Web.HttpContext.Current == null) return AppDomain.CurrentDomain.BaseDirectory;
else return Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"bin");
}
BasePath solution taken from: Why AppDomain.CurrentDomain.BaseDirectory not contains "bin" in asp.net app?
We're using it like this from within the migration: SqlFile(#"..\..\Sql\views\SomeView.sql");

Could not find a part of the path 'C:\Program Files (x86)\IIS Express\~\TextFiles\ActiveUsers.txt'

I tried many ways to access a text file in my Visual Studio 2012 Solution from a folder named TextFiles
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"~/TextFiles/ActiveUsers.txt", true))
{
file.WriteLine(model.UserName.ToString());
}
But it kept on throwing the error
Could not find a part of the path 'C:\Program Files (x86)\IIS
Express\~\TextFiles\ActiveUsers.txt'.
Not sure where I made a mistake
You need to use HttpServerUtility.MapPath which will turn the ~/ portion of the path in to the real location it resildes on your hard drive.
So that would change your code to (assuming you are in one of the IIS classes that expose a Server property to it's methods)
var path = Server.MapPath(#"~/TextFiles/ActiveUsers.txt");
using (System.IO.StreamWriter file = new System.IO.StreamWriter(path, true))
{
file.WriteLine(model.UserName.ToString());
}
I ran into a similar issue and ended up using
string sFileName = HttpContext.Current.Server.MapPath(#"~/dirname/readme.txt");
This is an old question but I just ran into this problem myself and wanted to add what I've just discovered, in case it's helpful to anyone else.
If you have UAC turned off but are not running with elevated permissions, and try to write to restricted files (e.g. the "Program Files" folder) you'll get the "could not find a part of the path" error, instead of the (correct) access denied error.
To eliminate the problem, run with elevated permissions as in this solution: https://stackoverflow.com/a/1885543/3838199
~ is not the "user home" or anything else in Windows. You can still set the path as relative to the working directory (where the executable is) by just not specifying a full path.
For .netcore 3.x
You should make use of IWebHostEnvironment using dependency injection.
You can then use it in your code this way
string wwwRootPath = _hostEnvironment.WebRootPath;
string path = Path.Combine(wwwRootPath, $"TextFiles{Path.PathSeparator}ActiveUsers.txt");
Ensure to use PathSeparator otherwise you might face the same error due to the variance in your hosting environment.

SQL Express connection string: mdf file location relative to application location

I am using SQL Express databases as part of a unit test project in c#. My databases is located here:
./Databases/MyUnitTestDB.mdf
I would like to use a relative path or variable in the app.config rather than having my connection string defined as:
AttachDbFilename=C:\blah\blah\blah\yea\yea\yea\MyApplication\Databases\MyUnitTestDB.mdf
I have seen the use of |DataDirectory| but am I correct in thinking this is only applicable to web applications?
I want to control this in the application configuration file, as in production the application uses a hosted sql database.
Thanks everyone, I used a combination of your responses.
In my app.config file my connection string is defined as follows
<add name="MyConnectionString"
connectionString="Server=.\SQLExpress;AttachDbFilename=|DataDirectory|\MyDatabase.mdf;Database=MyDatabaseForTesting;Trusted_Connection=Yes;" />
In my unit test class I set the DataDirectory property using the following
[TestInitialize]
public void TestInitialize()
{
AppDomain.CurrentDomain.SetData("DataDirectory", System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Databases"));
// rest of initialize implementation ...
}
Yes, |DataDirectory| Web application to select the App_Data directory of the web application.
In a not web application, depending on .NET Framework, it could be used and also changed using AppDomain.SetData
But you have other two posiblities to create the connection:
1.- Use a relative path:
String con ="... AttachDbFilename=Databases\MyUnitTestDB.mdf ... ";
2.- get the application path and add to the String.
In c# Windows Application you can use Application.StartupPath
String con= " ... AttachDbFilename=" + Application.StartupPath + "\Databases\MyUnitTestDB.mdf ... ";
Depending on the applicaiton type or launch mode you got different properties. Ex:
Application.StartupPath -- The start path of the exe application that starts the application
Application.ExecutablePath -- the start path an name of the exe application that stats the application
But to use Application you need to include System.Windows.Forms that is not included for example into console applications.
System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) -- This gets the path from the current assembly "dll,exe,..." Is not affected by application type, path changes,... Always return the directory when the Assemby resides.
Environment.CurrentDirectory -- the current directory. This can be changed for example if you navigate into folders.
You can find more about the different connection string options here
http://www.connectionstrings.com/sql-server-2005
I have spent a whole day googling to work this through and finally have a clue from this
Here is my solution:
1. Use |DataDirectory| in connection string
<add name="NorthwindConnectionString" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDbFilename=|DataDirectory|\Northwind.mdf;User Instance=True" providerName="System.Data.SqlClient" />
2.Set DataDirectory in ClassInitialize
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
int index = baseDir.IndexOf("TestResults");
string dataDir = baseDir.Substring(0, index) + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
}
I'm building a simple Windows Forms App with VS2010 with C#3.0. Also using SQL Express 2008 RC2.
I am able to use: |DataDirectory|MyDb.mdf in the connection string alone without changing anything else. The |DataDirectory| points to the location of my .exe file.
I will think that this would be the first thing all of you would try, so that is why I'm specifying my VS and SQL version. Or maybe it is new to C#3.0.
My complete Connection String:
"Server=.\SQLExpress;AttachDbFilename=|DataDirectory|App_Data\ThumbsUpPlayer.mdf;Database=ThumbsUpPlayer;Trusted_Connection=Yes;"
Note that I have added a "App_Data" folder to my application, because I'm used to the Db in that folder, the folder is not recognised by VS.
I don't have Visual Studio here, but what about:
using System.IO;
using System.Windows.Forms;
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
AttachDBFilme = appPath + "\\MyUnitTestDB.mdf"
I did the following. Hopefully it helps someone.
AppDomain.CurrentDomain.SetData("DataDirectory", System.IO.Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + "../../App_Data"));
Dynamic Path in SQL Server Connection
SqlConnection con="Server=.\SQLExpress;AttachDbFilename=|DataDirectory|\MyDatabase.mdf;Database=MyDatabaseForTesting;Trusted_Connection=Yes;" ;

Getting full path for Windows Service

How can I find out the folder where the windows service .exe file is installed dynamically?
Path.GetFullPath(relativePath);
returns a path based on C:\WINDOWS\system32 directory.
However, the XmlDocument.Load(string filename) method appears to be working against relative path inside the directory where the service .exe file is installed to.
Try
System.Reflection.Assembly.GetEntryAssembly().Location
Try this:
AppDomain.CurrentDomain.BaseDirectory
(Just like here: How to find windows service exe path)
Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location)
This works for our windows service:
//CommandLine without the first and last two characters
//Path.GetDirectory seems to have some difficulties with these (special chars maybe?)
string cmdLine = Environment.CommandLine.Remove(Environment.CommandLine.Length - 2, 2).Remove(0, 1);
string workDir = Path.GetDirectoryName(cmdLine);
This should give you the absolute path of the executable.
Another version of the above:
string path = Assembly.GetExecutingAssembly().Location;
FileInfo fileInfo = new FileInfo(path);
string dir = fileInfo.DirectoryName;
Environment.CurrentDirectory returns current directory where program is running. In case of windows service, returns %WINDIR%/system32 path that is where executable will run rather than where executable deployed.
This should give you the path that the executable resides in:
Environment.CurrentDirectory;
If not, you could try:
Directory.GetParent(Assembly.GetEntryAssembly().Location).FullName
A more hacky, but functional way:
Path.GetFullPath("a").TrimEnd('a')
:)

Categories