3

I'm using the Typewriter extension for Visual Studio and Visual Studio 2017. The following is the Typescript Template file.

${
    using System.IO;

    Template(Settings settings)
    {
        settings.IncludeProject("ProjectName");
    }

    string Test(Class c)
    {
        //return Path.GetDirectoryName(Path.GetDirectoryName( System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase ))); // > file:\C:\Users\[user]\AppData\Local
        //return Environment.CurrentDirectory; // > C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE
        return String.Join(", ", Directory.GetFiles("relative\path")); // > System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\relative\path'.
    }

}
$Classes(ProjectName.Models.*)[
export class $Name {
    $Properties[
    public $Name: $Type;]
    // $Test
}]

When using Directory.GetFiles the path is relative to C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE not relative to the template file or the project. How can I get relative files?

P.S. Not sure if this is specific to Typewriter or Visual Studio Extensions in general.

Edit
I have since tried DTE:

using EnvDTE;
DTE dte = (DTE)GetService(typeof(DTE));
string solutionDir = System.IO.Path.GetDirectoryName(dte.Solution.FullName);

But I get The type or namespace name 'EnvDTE' could not be found (are you missing a using directive or an assembly reference?) and i don't how to reference an assembly within an existing extension. If I could use DTE that would resolve the initial question.

Community
  • 1
  • 1
Wilhelmina Lohan
  • 2,803
  • 2
  • 29
  • 58
  • 1
    #reference EnvDTE #reference Microsoft.VisualStudio.Shell.15.0 But what is next? The solution dir is not a .tst template dir – Alex Buchatski Aug 24 '19 at 11:22
  • Just to expound on Alex's answer, if you add the following lines at the top of your file (outside the ${} brackets), it will give you access to EnvDTE and the DTE interface: `#reference EnvDTE #reference Microsoft.VisualStudio.Shell.15.0. ` However - it complains "The name 'GetService' does not exist in the current context". @AlexBuchatski, is there another reference I'm missing? – RocketMan Jan 13 '20 at 18:23

2 Answers2

0

The $Parent property of the class is a $File and this has a $FullName property which is the absolute file name. I am using this to get the filenames of the interface:

string FileName(Interface @interface)
{
   return (@interface.Parent as File).FullName;
}

Maybe from there you can figure out the path to the template file?

flayn
  • 5,272
  • 4
  • 48
  • 69
0

Thanks to the comments above I was able to pull this off with the following:

#reference EnvDTE 
#reference Microsoft.VisualStudio.Shell.15.0

${    
    Template(Settings settings)
    {
        EnvDTE.DTE dte = (EnvDTE.DTE)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(EnvDTE.DTE));
        var fileName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(dte.Solution.FullName), "myfile.txt");
    }

}
cs-NET
  • 496
  • 4
  • 3