WYB
2021-03-22 91b8cdad021ab052e4991f3d41834a6f0ddc36b8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<#@ assembly name="System.Core"#>
<#@ assembly name="EnvDTE"#>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#+
class Manager
{
    public struct Block {
        public int Start, Length;
        public String Name,OutputPath;
    }
 
    public List<Block> blocks = new List<Block>();
    public Block currentBlock;
    public Block footerBlock = new Block();
    public Block headerBlock = new Block();
    public ITextTemplatingEngineHost host;
    public ManagementStrategy strategy;
    public StringBuilder template;
    public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {
        this.host = host;
        this.template = template;
        strategy = ManagementStrategy.Create(host);
    }
    public void StartBlock(String name,String outputPath) {
        currentBlock = new Block { Name = name, Start = template.Length ,OutputPath=outputPath};
    }
 
    public void StartFooter() {
        footerBlock.Start = template.Length;
    }
 
    public void EndFooter() {
        footerBlock.Length = template.Length - footerBlock.Start;
    }
 
    public void StartHeader() {
        headerBlock.Start = template.Length;
    }
 
    public void EndHeader() {
        headerBlock.Length = template.Length - headerBlock.Start;
    }    
 
    public void EndBlock() {
        currentBlock.Length = template.Length - currentBlock.Start;
        blocks.Add(currentBlock);
    }
    public void Process(bool split) {
        String header = template.ToString(headerBlock.Start, headerBlock.Length);
        String footer = template.ToString(footerBlock.Start, footerBlock.Length);
        blocks.Reverse();
        foreach(Block block in blocks) {
            String fileName = Path.Combine(block.OutputPath, block.Name);
            if (split) {
                String content = header + template.ToString(block.Start, block.Length) + footer;
                strategy.CreateFile(fileName, content);
                template.Remove(block.Start, block.Length);
            } else {
                strategy.DeleteFile(fileName);
            }
        }
    }
}
class ManagementStrategy
{
    internal static ManagementStrategy Create(ITextTemplatingEngineHost host) {
        return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);
    }
 
    internal ManagementStrategy(ITextTemplatingEngineHost host) { }
 
    internal virtual void CreateFile(String fileName, String content) {
        File.WriteAllText(fileName, content);
    }
 
    internal virtual void DeleteFile(String fileName) {
        if (File.Exists(fileName))
            File.Delete(fileName);
    }
}
 
class VSManagementStrategy : ManagementStrategy
{
    private EnvDTE.ProjectItem templateProjectItem;
 
    internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host) {
        IServiceProvider hostServiceProvider = (IServiceProvider)host;
        if (hostServiceProvider == null)
            throw new ArgumentNullException("Could not obtain hostServiceProvider");
 
        EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
        if (dte == null)
            throw new ArgumentNullException("Could not obtain DTE from host");
 
        templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
    }
    internal override void CreateFile(String fileName, String content) {
        base.CreateFile(fileName, content);
        //((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);
    }
    internal override void DeleteFile(String fileName) {
        ((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);
    }
    private void FindAndDeleteFile(String fileName) {
        foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) {
            if (projectItem.get_FileNames(0) == fileName) {
                projectItem.Delete();
                return;
            }
        }
    }
}#>