I have been trying to find a way to create a class into a sub folder of a project. I can create a class that gets generated directly into the project root. I was looking at some built in actions, but couldn't find one that takes the projectitem, project folder and then put the item into the folder.
What I want to do is the following.
- Select Folder from wizard using solutioneditorpicker where file will be added. This will be of type ProjectItem.
- Create class using T4 template into folder selected in step 1.
Thanks |
| Gaurav76 Monday, July 09, 2007 1:33 PM |
For folder picker it's a more bit complex i think but thore custom action that do what you want it's very easy and not a lot different from standard additem action .... With standard "AddItem" output/input and another input action "destfolder" you can create an action with this code :
public override void Execute()
{
DTE vs = base.GetService<DTE>(true);
string path = Path.GetTempFileName();
using (StreamWriter writer = new StreamWriter(path, false))
{
writer.WriteLine(content);
}
ProjectItems whereToAdd;
if ((destFolder != String.Empty) && (destFolder != null))
{
whereToAdd = DteHelper.FindItemByName(this.project.ProjectItems, destFolder, true).ProjectItems;
}
else
{
whereToAdd = this.project.ProjectItems;
}
this.projectItem = whereToAdd.AddFromTemplate(path, this.targetFileName);
if (this.open)
{
Window window = this.ProjectItem.Open("{00000000-0000-0000-0000-000000000000}");
window.Visible = true;
window.Activate();
}
File.Delete(path);
}
Regards, |
| MephistoDark Tuesday, July 10, 2007 5:07 AM |
Hello,
what i give you is code sample for Execute method of a new Action (for example we can call it AddItemToFolderFromStringAction in the Namespace "A.Actions" So your package file would be something like : [...]
<Action Open="true" Type="A.Actions.AddItemToFolderFromStringAction, A" Name="AddClass">
<Input Name="Content" ActionOutput="GenerateDAC.Content" />
<Input Name="TargetFileName" RecipeArgument="TargetFile" />
<Input Name="Project" RecipeArgument="CurrentProject" />
<Input Name="Open" />
<Input Name="DestFile" /> <!-- With DestFile your input property in Action class-->
<Output Name="ProjectItem" />
</Action>
You have to create a new Action because all job is in Execute method. Take a look at the existing one with reflector, code is quite the same (just the "FindItem" added in above snippet)
Regards,
|
| MephistoDark Wednesday, July 11, 2007 8:53 PM |
For folder picker it's a more bit complex i think but thore custom action that do what you want it's very easy and not a lot different from standard additem action .... With standard "AddItem" output/input and another input action "destfolder" you can create an action with this code :
public override void Execute()
{
DTE vs = base.GetService<DTE>(true);
string path = Path.GetTempFileName();
using (StreamWriter writer = new StreamWriter(path, false))
{
writer.WriteLine(content);
}
ProjectItems whereToAdd;
if ((destFolder != String.Empty) && (destFolder != null))
{
whereToAdd = DteHelper.FindItemByName(this.project.ProjectItems, destFolder, true).ProjectItems;
}
else
{
whereToAdd = this.project.ProjectItems;
}
this.projectItem = whereToAdd.AddFromTemplate(path, this.targetFileName);
if (this.open)
{
Window window = this.ProjectItem.Open("{00000000-0000-0000-0000-000000000000}");
window.Visible = true;
window.Activate();
}
File.Delete(path);
}
Regards, |
| MephistoDark Tuesday, July 10, 2007 5:07 AM |
First of all thanks MephistoDark for getting back to me. But I just want to clarify something with you.
Below is the code that I currently have:
< Actions>
< Action Type="IvyIrisPackage.Actions.GetTableSchemaAction, IvyIrisPackage" Name="GetTableSchema">
< Input Name="ProviderName" RecipeArgument="DataProvider" />
< Input Name="ConnectionString" RecipeArgument="ConnectionString" />
< Input Name="TableName" RecipeArgument="TableName" />
< Output Name="TableSchema" />
< Output Name="Indexes" />
</ Action>
< Action Template="Items\ClassTemplate.cs.t4" Type="Microsoft.Practices.RecipeFramework.VisualStudio.Library.Templates.TextTemplateAction, Microsoft.Practices.RecipeFramework.VisualStudio.Library" Name="GenerateDAC">
< Input Name="Table" ActionOutput="GetTableSchema.TableSchema" />
< Input Name="ClassName" RecipeArgument="ClassName" />
< Input Name="TargetNamespace" RecipeArgument="TargetNamespace" />
< Output Name="Content" />
</ Action>
< Action Open="true" Type="Microsoft.Practices.RecipeFramework.Library.Actions.AddItemFromStringAction, Microsoft.Practices.RecipeFramework.Library" Name="AddClass">
< Input Name="Content" ActionOutput="GenerateDAC.Content" />
< Input Name="TargetFileName" RecipeArgument="TargetFile" />
< Input Name="Project" RecipeArgument="CurrentProject" />
< Input Name="Open" />
< Output Name="ProjectItem" />
</ Action>
</ Actions>
So would I create a new action after AddItemFromStringAction or would I use what you provided in place of that action? Is your snippent also inheriting from AddItemStringAction?
Thanks,
Gaurav |
| Gaurav76 Tuesday, July 10, 2007 5:35 PM |
Hello,
what i give you is code sample for Execute method of a new Action (for example we can call it AddItemToFolderFromStringAction in the Namespace "A.Actions" So your package file would be something like : [...]
<Action Open="true" Type="A.Actions.AddItemToFolderFromStringAction, A" Name="AddClass">
<Input Name="Content" ActionOutput="GenerateDAC.Content" />
<Input Name="TargetFileName" RecipeArgument="TargetFile" />
<Input Name="Project" RecipeArgument="CurrentProject" />
<Input Name="Open" />
<Input Name="DestFile" /> <!-- With DestFile your input property in Action class-->
<Output Name="ProjectItem" />
</Action>
You have to create a new Action because all job is in Execute method. Take a look at the existing one with reflector, code is quite the same (just the "FindItem" added in above snippet)
Regards,
|
| MephistoDark Wednesday, July 11, 2007 8:53 PM |
Thanks for the reply. I actually was able to figure it out and get it done yesterday. But without your sample code I wouldn't have gotten it done.
It's just hard figuring this stuff out without documentation. The example installed with GAX does help. Once again thanks for your help. |
| Gaurav76 Wednesday, July 11, 2007 9:00 PM |
Happy to help you. Good job. |
| MephistoDark Wednesday, July 11, 2007 9:01 PM |
Really helped me a lot. thanks |
| satish padidem Thursday, January 10, 2008 1:19 PM |
Hello
I got a solution with lots of projects and folders but some of the folders have the same name. With MephistoDark his code you can search for the folder but if you have the same foldername in another project then you might put the generated file in de wrong folder. How can you put the generated file into a subfolder of a subfolder in a project giving a path? Can anybody help me with this?
Regards - Edited byAgostin Tuesday, April 21, 2009 1:23 PM
-
|
| Agostin Tuesday, April 21, 2009 7:25 AM |
I solved my problem :)
DteHelper.FindItemByPath(root, destFolder).ProjectItems;
I put also another property in the code because you need the rootpath to search with FindItemByPath
[Input(Required = true)] public Solution Root { get { return root; } set { root = value; } }
and you got toput an extra input into your package file, like this:
<Input Name="root" RecipeArgument="rootPath" />
This thread helped me a lot. Thanks!
|
| Agostin Tuesday, April 21, 2009 1:17 PM |