t4 templte is located outside of directory of target project - c#

at one solution,t4 template file was in Frame.Model project
var path = solutionPath+#"\Frame.Service\Interface\"+config.FileName;
config.Output.Encoding = Encoding.UTF8;
config.RenderToFile(path);
This will generate code to another project,but wrong,
message:
*13 Output file D:\Code\Frame.Web\Frame.Service\Interface\IUser.generated.cs is located outside of directory of target project
D:\Code\Frame.Web\Frame.Model\Frame.Model.csproj
D:\Code\Frame.Web\Frame.Model\T4\EntityCodeScript.tt 1 1 Frame.Model*
when I change to:
var path = solutionPath+#"\Frame.Model\Interface\"+config.FileName;
That successes, why can't generate file in diffrence project?
how do? thk!!!
sorry i am enlish is very bad , i hope you can know whats this

you need to add template.Output.Project. check this article .
http://www.olegsych.com/2009/03/t4-toolbox-generating-files-in-different-folders-and-projects/

Related

What is the best way to find directory path from an EF migration script?

I'm using Entity Framework code first migrations in my project. One of these migrations populates a database table by reading in data from csv files located in a directory in the project. The project structure looks like this:
- Soulution
- Project
- Migrations
- CSVFolder
- file1.csv
- file2.csv
- Migration1.cs
- Migration2.cs
In my Up() method, I get these files like so:
public override void Up()
{
var migrationsDir = AppDomain.CurrentDomain.BaseDirectory + "/Migrations/CSVFolder/"; // For some reason, Path.Combine() doesn't work for me here so I manually concatenate the strings.
var templateFiles = Directory.GetFiles(migrationsDir, "*.csv");
foreach (var filename in templateFiles)
{
Sql(); // SQL Insert statement here.
}
}
This runs fine on my dev machine but when I deploy this to the test server with Octopus, I get a path not found exception
Could not find a part of the path
'C:\Octopus\Applications\Test\Solution\1.1-alpha21\Migrations\CSVFolder'.
I've checked the 'drop' folder and the output there includes Migrations > CSVFolder.
I've tried a few different ways to get the path to the folder but they work either locally or on the server. What's the best way to get the path that will work both locally and on the server?
You have to set the path correctly! AppDomain.CurrentDomain.BaseDirectory will returns in case of testing the test runner directory and in the application mode you will get ..\Bin\Debug etc. You have to check how many directories you have until you can reach the desired location(CSVFolder) and then replace the path or change it for example :
var migrationsDir = AppDomain.CurrentDomain.BaseDirectory + "../../Migrations/CSVFolder/"; // For some reason, Path.Combine() doesn't work for me here so I manually concatenate the strings.
You have noticed that is not easy what you are trying to do so you can forget this apporach and this is the trick. The best way is just attach the cvs files to the assembly resources! and during the migrations you can access them like the following:
in Up()
var file1 = Properties.Resources.File1;
This approach will guarantee that the Sql or Cvs files will always attached/loaded to the assembly at the runtime.
This works for me
AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory

Nancy.ViewEngines.ViewNotFoundException: Unable to locate view 'Index'

I know this question was asked month before but was never answered.
My program starts normally but after returning View["Index", blogPost] it could not find the Index.cshtml and raises an exception.
Get["/"] = parameters =>
{
var blogPost = new BlogPost
{
Id = 1,
Title = "Test",
Content = "Lorem ipsum...",
Tags = { "c#", "aspnetmvc", "nancy" }
};
return View["Index", blogPost];
};
Exception:
Nancy.RequestExecutionException: Oh noes! ---> Nancy.ViewEngines.ViewNotFoundException: Unable to locate view 'Index'
Currently available view engine extensions: sshtml,html,htm,cshtml,vbhtml
Locations inspected: views/Home/Index-de-DE,views/Home/Index,Home/Index-de-DE,Home/Index,views/Index-de-DE,views/Index,Index-de-DE,Index`
If the answer giving my Christian doesn't help you like it didn't help me there is a alternative issue/solution. The alternative is to make sure that the file you created is being copied to the output directory at compile time. You can check it under the properties tab like shown bellow
The exception message tells you where Nancy tried to look for the view:
Locations inspected: views/Home/Index-de-DE,views/Home/Index,Home/Index-de-DE,Home/Index,views/Index-de-DE,views/Index,Index-de-DE,Index
The exception also tells you which file extensions Nancy tried to look for:
Currently available view engine extensions: sshtml,html,htm,cshtml,vbhtml
That is Nancy looks for a file in one of the listed locations with one of the listed extensions.
So the question is if your index.cshtml is in one the listed folders. If not you can either move it there or set up a view location convention.
We ran into this error and noticed the .cshtml file it was complaining about was not getting copied to the server. The solution was in Visual Studio, in the file's properties, we changed the Build Action to Content. This forces it to get included in the build artifacts that are deployed to the server. Similarly you could change the Copy to Output Directory to Always as others have mentioned; either works, but I find setting the file as Content a bit more informative.
In your case, I'm guessing you have an Index.cshtml file which you need to set this property on.

How to get Directory while running unit test

Hi when running my unit test I'm wanting to get the directory my project is running in to retrieve a file.
Say I have a Test project named MyProject. Test I run:
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
and I receive "C:\\Source\\MyProject.Test\\bin\\Debug".
This is close to what I'm after. I don't want the bin\\Debug part.
Anyone know how instead I could get "C:\\Source\\MyProject.Test\\"?
I would do it differently.
I suggest making that file part of the solution/project. Then right-click -> Properties -> Copy To Output = Copy Always.
That file will then be copied to whatever your output directory is (e.g. C:\Source\MyProject.Test\bin\Debug).
Edit: Copy To Output = Copy if Newer is the better option
Usually you retrieve your solution directory (or project directory, depending on your solution structure) like this:
string solution_dir = Path.GetDirectoryName( Path.GetDirectoryName(
TestContext.CurrentContext.TestDirectory ) );
This will give you the parent directory of the "TestResults" folder created by testing projects.
Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
This will give you the directory you need....
as
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
gives nothing but
Directory.GetCurrentDirectory().
Have alook at this link
http://msdn.microsoft.com/en-us/library/system.appdomain.currentdomain.aspx
Further to #abhilash's comment.
This works in my EXE's, DLL's and when tested from a different UnitTest project in both Debug or Release modes:
var dirName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.Replace("bin\\Debug", string.Empty));
/// <summary>
/// Testing various directory sources in a Unit Test project
/// </summary>
/// <remarks>
/// I want to mimic the web app's App_Data folder in a Unit Test project:
/// A) Using Copy to Output Directory on each data file
/// D) Without having to set Copy to Output Directory on each data file
/// </remarks>
[TestMethod]
public void UT_PathsExist()
{
// Gets bin\Release or bin\Debug depending on mode
string baseA = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
Console.WriteLine(string.Format("Dir A:{0}", baseA));
Assert.IsTrue(System.IO.Directory.Exists(baseA));
// Gets bin\Release or bin\Debug depending on mode
string baseB = AppDomain.CurrentDomain.BaseDirectory;
Console.WriteLine(string.Format("Dir B:{0}", baseB));
Assert.IsTrue(System.IO.Directory.Exists(baseB));
// Returns empty string (or exception if you use .ToString()
string baseC = (string)AppDomain.CurrentDomain.GetData("DataDirectory");
Console.WriteLine(string.Format("Dir C:{0}", baseC));
Assert.IsFalse(System.IO.Directory.Exists(baseC));
// Move up two levels
string baseD = System.IO.Directory.GetParent(baseA).Parent.FullName;
Console.WriteLine(string.Format("Dir D:{0}", baseD));
Assert.IsTrue(System.IO.Directory.Exists(baseD));
// You need to set the Copy to Output Directory on each data file
var appPathA = System.IO.Path.Combine(baseA, "App_Data");
Console.WriteLine(string.Format("Dir A/App_Data:{0}", appPathA));
// C:/solution/UnitTestProject/bin/Debug/App_Data
Assert.IsTrue(System.IO.Directory.Exists(appPathA));
// You can work with data files in the project directory's App_Data folder (or any other test data folder)
var appPathD = System.IO.Path.Combine(baseD, "App_Data");
Console.WriteLine(string.Format("Dir D/App_Data:{0}", appPathD));
// C:/solution/UnitTestProject/App_Data
Assert.IsTrue(System.IO.Directory.Exists(appPathD));
}
I normally do it like that, and then I just add "..\..\" to the path to get up to the directory I want.
So what you could do is this:
var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + #"..\..\";
For NUnit this is what I do:
// Get the executing directory of the tests
string dir = NUnit.Framework.TestContext.CurrentContext.TestDirectory;
// Infer the project directory from there...2 levels up (depending on project type - for asp.net omit the latter Parent for a single level up)
dir = System.IO.Directory.GetParent(dir).Parent.FullName;
If required you can from there navigate back down to other directories if required:
dir = Path.Combine(dir, "MySubDir");
According to https://github.com/nunit/nunit/issues/742#issuecomment-121964506
For NUnit3 , System.Environment.CurrentDirector is never changed, so it shall be the path of solution.
Eg:
string szProjectPath = System.Environment.CurrentDirectory + #"\where\your\project\is";
I prefer fixed location rather than GetParent().
One drawback of GetParent is when build is changed from AnyCPU to x86, default path would be changed from bin\Debug to bin\x86\Debug.
Need to get another parent, and it's pain in the neck.
Also, you may still access to you test assemblies at TestContext.CurrentContext.TestDirectory and get output from TestContext.CurrentContext.WorkDirectory
Edit:
Note: There are many changes in NUnit3. I will suggest reading through the documentation about "Breaking changes"
The best solution I found was to put the file as an embedded resource on the test project and get it from my unit test. With this solution I don´t need to care about file paths.
I'm not sure if this helps, but this looks to be briefly touched on in the following question.
Visual Studio Solution Path environment variable
In general you may use this, regardless if running a test or console app or web app:
// returns the absolute path of assembly, file://C:/.../MyAssembly.dll
var codeBase = Assembly.GetExecutingAssembly().CodeBase;
// returns the absolute path of assembly, i.e: C:\...\MyAssembly.dll
var location = Assembly.GetExecutingAssembly().Location;
If you are running NUnit, then:
// return the absolute path of directory, i.e. C:\...\
var testDirectory = TestContext.CurrentContext.TestDirectory;
My approach relies on getting the location of the unit testing assembly and then traversing upwards. In the following snippet the variable folderProjectLevel will give you the path to the Unit test project.
string pathAssembly = System.Reflection.Assembly.GetExecutingAssembly().Location;
string folderAssembly = System.IO.Path.GetDirectoryName(pathAssembly);
if (folderAssembly.EndsWith("\\") == false) {
folderAssembly = folderAssembly + "\\";
}
string folderProjectLevel = System.IO.Path.GetFullPath(folderAssembly + "..\\..\\");
You can do it like this:
using System.IO;
Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, #"..\..\"));
use StackTrace
internal static class Extensions
{
public static string GetSourceDirectoryName(this Type type)
{
StackTrace stackTrace = new StackTrace(true);
foreach (var frame in stackTrace.GetFrames())
{
if (frame.GetMethod() is { } method && method.DeclaringType == type)
{
return Path.GetDirectoryName(frame.GetFileName());
}
}
throw new Exception($"未找到{type.Name}源文件目录");
}
}

Visual Studio Installer > PostBuildEvent error code '1'

I'm trying to run a .js file with PostBuildEvent in Visual Studio 2010 and fail when i build the solution with the error code
Error 2 'PostBuildEvent' failed with error code '1' 'Error no especificado'
I already check the names of the files, the path, and the code in my project and js file, and everything seems right...
the js file contain this
// http://blogs.msdn.com/b/heaths/archive/2006/02/01/64-bit-managed-custom-actions-with-visual-studio.aspx
var msiOpenDatabaseModeTransact = 1;
var msiViewModifyUpdate = 2
var filespec = WScript.Arguments(0);
var projdir = WScript.Arguments(1);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
// Update the Binary table...
var sql = "SELECT `Name`,`Data` FROM `Binary` where `Binary`.`Name` = 'InstallUtil'";
var view = database.OpenView(sql);
view.Execute();
var record = view.Fetch();
record.SetStream(2, projdir + "InstallUtilLib.dll");
view.Modify(msiViewModifyUpdate, record);
view.Close();
database.Commit();
Anyone already solve a problem like this??
Any help, please...
Since you are using Visual Studio Installer, location of JS File is also important. Your js file should be in the same directory as the .vdproj file for your setup project.
This should be of some help to you
http://blogs.msdn.com/b/astebner/archive/2006/08/12/696833.aspx
In a desperate attempt to solve the problem, I found the solution.
After checking everything else, i move my project to another folder, and I discovered that the path was too long.
The path of my project, despite having less than 255 characters, as indicated by the Microsoft site, cause the Visual Studio 2010 give back this error.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
But attention, being a little explanatory error may result from other errors in other cases. In my case solved the problem.

What is the best way to get the executing exe's path in .NET?

From program a.exe located in c:/dir I need to open text file c:/dir/text.txt. I don't know where a.exe could be located, but text.txt will always be in the same path. How to get the name of the currently executing assembly from within to program itself so that i can access the text file?
EDIT:
what if a.exe is a Windows service? It doesn't have Application as it is not a Windows Applicaion.
I usually access the directory that contains my application's .exe with:
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
string exePath = Application.ExecutablePath;
string startupPath = Application.StartupPath;
EDIT -
Without using application object:
string path = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
See here for more info:
http://msdn.microsoft.com/en-us/library/aa457089.aspx
Application.ExecutablePath
Application.StartupPath
Get the assembly you are interested in (eg. assigned to a System.Reflection.Assembly a variable):
System.Reflection.Assembly.GetEntryAssembly(), or
typeof(X).Assembly for a class X that's in the assembly you're interested in (for Windows Forms you could use typeof(Program))
Then get the path of where the file from which that assembly a was loaded from:
System.IO.Path.GetDirectoryName(a.Location)
The Application object from a Windows Forms application is also a possibility, as explained in other answers.
In VB.NET we can get it in following way:
Assembly.GetEntryAssembly.Location
In C#:
Assembly.GetEntryAssembly().Location
using peSHlr's answer worked well when testing in NUnit as well.
var thisType = typeof(MyCustomClass);
var codeLocation = Path.GetDirectoryName(thisType.Assembly.Location);
var codeLocationPath = Path.GetDirectoryName(codeLocation);
var appConfigPath = Path.Combine(codeLocationPath, "AppConfig");
MessageBox.Show("This program is located in: " + Environment.CurrentDirectory);

Categories

Resources