Auto formatting a t4 created file - c#

I'm currently creating many files using t4 templates in vs2015.
My code comes out all misaligned (it's worst in other spot of the generated code)
example -
public bool Add()
{
var returnValue = false;
using (var context = new ApmEntities())
{
context.Entry(this).State = EntityState.Added;
foreach (var item in this.MissionCriticalities)
{
context.Entry(item).State = EntityState.Modified;
}
var number = context.SaveChanges();
returnValue = number > 0;
}
return returnValue;
}
Is there a way to automatically run formatting (similar to doing Ctrl - K - D) on the file?
I'm creating the file with
fileManager.StartNewFile(entity.Name + "DbExtra" + ".cs");
and at the end of the file doing a
fileManager.Process();
(Similar to the t4 that generates objects when using database first entity framework)
Thanks

You can format it with "\t" or "\n" or normale spaces directly in your file creation. It depends on how your "CreationFile" looks like and how this is formated.
I don't think that you can format that in another way per code, because with your t4 script you will say how the file should look like.
But what you also can try is:
Use the CodeCleanup From Resharper, if you have, and write a macro which will save every "Save" action of a file:
How can I configure ReSharper's code cleanup on save?
I use that and its very great. Its formated the different files in that way which I want, sorted properties, usings and much more.
Try it :-)

Related

Adding existing project into new VS2012 solution programmatically fails

We have the following code in wizard to add existing project to a new solution:
//generating files
if (dte.Solution.Projects.Count < 1) // Solution is empty or doesn't exist
{
dte.Solution.Create(oneFolderHigher(Params.OutputDir, solutionName),
solutionFileName(solutionName));
}
// adding created project to solution
dte.Solution.AddFromFile(Path.Combine(Params.ProjectRootFolder,
Params.ProjectName + ".csproj"));
It works just fine under MS Visual Studio 2010, but fails under 2012 (I experimented with second parameter):
System.Runtime.InteropServices.COMException (0x80004004): Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT))
at EnvDTE.SolutionClass.AddFromFile(String FileName, Boolean Exclusive)
at Wizard.Generator.NewProjectGenerator.Generate(Action`1 logMessage)
at Wizard.Forms.WizardForm.Finish()
After this error I'm adding the new project to the solution manually and everything works OK. But we can not just say, "Sorry, we can not add newly generated project for you so please add it by yourself."
MSDN proposes:
You can use the LaunchWizard method rather than AddFromFile to execute a wizard if you want to suppress its UI during execution. LaunchWizard has a parameter that allows you to disable the UI.
But this method requires some wizard file, so it can not be a solution.
Could someone help?
Wizard is running from "New -> Project" menu.
Here the workaround for the issue (proposed by my boss):
Before adding the project to solution, project file should be converted to
VS2012 format.
But code is little ugly:
using (StreamReader sr = new StreamReader(newFile))
using (StreamWriter sw = new StreamWriter(projectFile, false, Encoding.UTF8))
{
while (sr.Peek() >= 0)
{
string s = sr.ReadLine();
if (s.Contains("<Project ToolsVersion=\"4.0\""))
{
s = s + Environment.NewLine + importProject;
}
... and so on
Maybe someone knows the way to do it awesome? I mean converting. I'll let the question to be unanswered some time. Waiting for your comments.

Using an IF statement in my SiteMaster.cs file

In my SiteMaster.cs file I want to be able to run an IF statement based on the current page the user is on.
I'm currently getting the file name using: currentPage.Text = this.Page.ToString().Substring(4, this.Page.ToString().Substring(4).Length - 5) + ".aspx"; but I'd like to then use this to run an IF statement.
It would basically be like (if currentPage == "default.aspx") { // do this }
I'm very new to .NET and taking on a existing project.
Can anyone point me in the right direction to achieve this?
Many thanks
You need to get the page name from the Request.Url.AbsoluteUri.
if(Request.Url.AbsolutePath.Contains("Default.aspx"))
Or, below will return Default.aspx
Request.Url.AbsolutePath.Substring(Request.Url.AbsolutePath.LastIndexOf('/')+1)
Its alot better to compare type. Every page is a class.
if(Page is _Default)
{
// do work
}
If you have to import a namespace and you have visual studio 2010 you can highlight _Default and holding CTRL + .

Getting the selected file and using IVsSingleFileGenerator

I am trying to add several new functions to a package I developed for our company. One of these functions is to create a new file based on the file selected in the solution explorer and the menu option selected. I have created my dynamic menu items that are on the solution explorer and it looks like I need to use IVsSingleFileGenerator as shown in this sample.
The trouble I am having is getting the file I have selected and either reading it or passing it into a single file generator.
I would rather generate the file from this context menu than from a custom tool action
Looks like this will get me the path of the file
UIHierarchy solutionExplorer = _applicationObject.ToolWindows.SolutionExplorer;
var items = solutionExplorer.SelectedItems as Array;
if (items == null || items.Length != 2)
{
return;
}
String strFile1 = String.Empty;
UIHierarchyItem item1 = items.GetValue(0) as UIHierarchyItem;
foreach (UIHierarchyItem hierarchyItem in items)
{
ProjectItem prjItem = hierarchyItem.Object as ProjectItem;
string prjPath = prjItem.Properties.Item("FullPath").Value.ToString();
}
which I can then use to pass into the generate function of the ivs single file generator.
Is this the best approach?
I also posted this question to the msdn forums at:
VSX getting the selected file and using IVsSingleFileGenerator
I ended up using the IPyIntegration sample to figure out what i needed to do.

Text in file is not appended - C#

I've decided to add a logging mechanism to my application so I can catch any errors or exceptions that are thrown. I've noticed that when an entry to the log is created it is not added to the log, it seems to overwrite everything that is in the file so there is only ever one entry.
I have a feeling it's something simple that I'm missing but I don't really use the System.IO namespace very often.
Creating/Checking for the log file:
public static void SetWorkingDirectory(string path)
{
_workingDirectory = path + "\\ErrorLog.txt";
if(!File.Exists(_workingDirectory))
{
File.Create(_workingDirectory);
}
pathSet = true;
}
Adding to the log:
public static bool Add(string message)
{
StringBuilder str = new StringBuilder();
str.Append(System.DateTime.Now);
str.Append(" ");
str.Append(message);
str.Append(" \n");
using (StreamWriter writer = new StreamWriter(_workingDirectory))
{
writer.Write(str.ToString());
}
return true;
}
The log itself:
Try using this constructor and passing true for the second argument so it opens the file in append mode.
...
using(writer = new StreamWriter(_workingDirectory, true))
...
Just use the overload of StreamWriter that takes a bool to determine if it should append.
using (var writer = new StreamWriter(_workingDirectory, true)
{
...
}
That StreamWriter constructor you are using, overwrites the file. There is an overload which will append:
using (StreamWriter writer = new StreamWriter(_workingDirectory, true))
It is all in the docs.
Also, unless this for learning, use one of the many available logging frameworks instead. Logging can be hard to get right.
Many programming hours have been spent solving this problem before. I recommend using a logging package such as log4net instead to save yourself time debugging code that is intended to let you instrument the code you are writing.
As driis has stated above, when performing logging its best to use one of the ready made logging frameworks, as without an extreme amount of effort they will be able to do it more efficiently and cleaner than you will. My favourite in .NET is to use the prepackaged System.Diagnostics tracing utilities which allow you to declare a tracelistener(s) in your app config then simply write to them in your code like this:
Trace.Write("Test output ");
Alternatively you could use the log4Net framework.

How do I find and open a file in a Visual Studio 2005 add-in?

I'm making an add-in with Visual Studio 2005 C# to help easily toggle between source and header files, as well as script files that all follow a similar naming structure. However, the directory structure has all of the files in different places, even though they are all in the same project.
I've got almost all the pieces in place, but I can't figure out how to find and open a file in the solution based only on the file name alone. So I know I'm coming from, say, c:\code\project\subproject\src\blah.cpp, and I want to open c:\code\project\subproject\inc\blah.h, but I don't necessarily know where blah.h is. I could hardcode different directory paths but then the utility isn't generic enough to be robust.
The solution has multiple projects, which seems to be a bit of a pain as well. I'm thinking at this point that I'll have to iterate through every project, and iterate through every project item, to see if the particular file is there, and then get a proper reference to it.
But it seems to me there must be an easier way of doing this.
To work generically for any user's file structure, you'll need to enumerate all the files in all the projects. This should get you started. And, well, pretty much finished :-)
internal static string GetSourceOrInclude(bool openAndActivate)
{
// Look in the project for a file of the same name with the opposing extension
ProjectItem thisItem = Commands.Application.ActiveDocument.ProjectItem;
string ext = Path.GetExtension(thisItem.Name);
string searchExt = string.Empty;
if (ext == ".cpp" || ext == ".c")
searchExt = ".h";
else if (ext == ".h" || ext == ".hpp")
searchExt = ".cpp";
else
return(string.Empty);
string searchItemName = thisItem.Name;
searchItemName = Path.ChangeExtension(searchItemName, searchExt);
Project proj = thisItem.ContainingProject;
foreach(ProjectItem item in proj.ProjectItems)
{
ProjectItem foundItem = FindChildProjectItem(item, searchItemName);
if (foundItem != null)
{
if (openAndActivate)
{
if (!foundItem.get_IsOpen(Constants.vsViewKindCode))
{
Window w = foundItem.Open(Constants.vsViewKindCode);
w.Visible = true;
w.Activate();
}
else
{
foundItem.Document.Activate();
}
}
return(foundItem.Document.FullName);
}
return(string.Empty);
}
Note that it is possible for a header to be in the include path without being added to the project, so if the above fails, you could potentially look in the include paths for the containing project too. I'll leave that as an exercise for the reader.

Categories

Resources