-
Notifications
You must be signed in to change notification settings - Fork 16
/
API_MicrosoftBuild.cs
268 lines (223 loc) · 10.9 KB
/
API_MicrosoftBuild.cs
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
using System;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections.Generic;
using O2.Views.ASCX.ExtensionMethods;
using O2.DotNetWrappers.DotNet;
using O2.DotNetWrappers.Windows;
using O2.DotNetWrappers.ExtensionMethods;
using O2.External.SharpDevelop.ExtensionMethods;
using Microsoft.Build.Logging;
using Microsoft.Build.Evaluation;
//O2Ref:Microsoft.Build.Framework.dll
//O2Ref:Microsoft.Build.dll
namespace O2.XRules.Database.APIs
{
public class API_MicrosoftBuild
{
public string DefaultProgramFile = "Program_UseWith_O2_CreatedExes";
}
public static class API_MicrosoftBuild_ExtensionMethods
{
public static string createProjectFile(this string projectName, string sourceFile, string pathToAssemblies, string targetDir)
{
return projectName.createProjectFile(sourceFile, pathToAssemblies, targetDir, new List<string>(),null,null);
}
public static string createProjectFile(this string projectName, string sourceFile, string pathToAssemblies, string targetDir, List<string> extraEmbebbedResources, Action<List<string>> beforeAddingReferences, Action<List<string>> beforeEmbedingFiles)
{
sourceFile.file_Copy(targetDir);
var assemblyFiles = pathToAssemblies.files(false,"*.dll","*.exe");
//NOT WORKING: hack to not include dlls that are already embedded inside the O2_FluentSharp_REPL
/* if (assemblyFiles.fileNames().contains("O2_FluentSharp_REPL.dll"))
foreach(var file in assemblyFiles.toList())
if(file.fileName().info() == "O2_FluentSharp_CoreLib.dll" ||
file.fileName().info() == "O2_FluentSharp_BCL.dll" ||
file.fileName().info() == "O2_External_SharpDevelop.dll")
{
assemblyFiles.remove(file);
"REMOVING {0}".error(file);
}*/
var projectFile = targetDir.pathCombine(projectName + ".csproj");
var projectCollection = new ProjectCollection();
var outputPath = "bin";
Project project = new Project(projectCollection);
project.SetProperty("DefaultTargets", "Build");
var propertyGroup = project.Xml.CreatePropertyGroupElement();
project.Xml.InsertAfterChild(propertyGroup, project.Xml.LastChild);
propertyGroup.AddProperty("TargetFrameworkVersion", "v4.0");
propertyGroup.AddProperty("ProjectGuid", Guid.NewGuid().str());
propertyGroup.AddProperty("OutputType", "WinExe");
propertyGroup.AddProperty("OutputPath", outputPath);
propertyGroup.AddProperty("AssemblyName", projectName);
propertyGroup.AddProperty("PlatformTarget", "x86");
var targets = project.Xml.AddItemGroup();
targets.AddItem("Compile", sourceFile.fileName());
var references = project.Xml.AddItemGroup();
references.AddItem("Reference", "mscorlib");
references.AddItem("Reference", "System");
references.AddItem("Reference", "System.Core");
references.AddItem("Reference", "System.Windows.Forms");
beforeAddingReferences.invoke(assemblyFiles);
foreach(var assemblyFile in assemblyFiles)
{
var assembly = assemblyFile.fileName().assembly(); // first load from local AppDomain (so that we don't lock the dll in the target folder)
if (assembly.isNull())
assembly = assemblyFile.assembly();
//only load the O2 assemblies
if (assembly.str().lower().contains("o2"))
{
var item = references.AddItem("Reference",assemblyFile.fileName_WithoutExtension());
item.AddMetadata("HintPath",assemblyFile.fileName());
item.AddMetadata("Private",@"False");
}
}
var gzAssemblyFiles = new List<string>();
beforeEmbedingFiles.invoke(assemblyFiles);
foreach(var assemblyFile in assemblyFiles)
{
var gzFile = targetDir.pathCombine(assemblyFile.fileName() + ".gz");
assemblyFile.fileInfo().compress(gzFile);
assemblyFile.file_Copy(targetDir);
gzAssemblyFiles.add(gzFile);
}
var embeddedResources = project.Xml.AddItemGroup();
foreach(var assemblyFile in gzAssemblyFiles)
embeddedResources.AddItem("EmbeddedResource",assemblyFile.fileName());
var defaultIcon = "O2Logo.ico";
foreach(var extraResource in extraEmbebbedResources)
{
extraResource.file_Copy(targetDir);
embeddedResources.AddItem("EmbeddedResource",extraResource.fileName());
if (extraResource.extension(".ico"))
defaultIcon = extraResource;
}
//add two extra folders (needs refactoring)
Action<string> addSpecialResources =
(resourceFolder)=>{
var folder = targetDir.pathCombine(resourceFolder);
if (folder.dirExists())
{
"found {0} Folder so adding it as a zip:{1}".debug(resourceFolder, folder);
var zipFile = folder.zip_Folder(folder + ".zip");
embeddedResources.AddItem("EmbeddedResource",zipFile.fileName());
if (folder.files("*.ico").size()>0)
{
var icon = folder.files("*.ico").first();
"Found default application ICON: {0}".debug(icon);
defaultIcon = icon;
}
}
};
addSpecialResources("O2.Platform.Scripts");
addSpecialResources(projectName + ".Data");
//now add the icon
propertyGroup.AddProperty("ApplicationIcon", defaultIcon);
var importElement = project.Xml.CreateImportElement(@"$(MSBuildToolsPath)\Microsoft.CSharp.targets");
project.Xml.InsertAfterChild(importElement, project.Xml.LastChild);
project.Save(projectFile);
"O2Logo.ico".local().file_Copy(targetDir);
return projectFile;
}
public static bool buildProject(this string projectFile, bool redirectToConsole = false)
{
try
{
var fileLogger = new FileLogger();
var logFile = projectFile.directoryName().pathCombine(projectFile.fileName() + ".log");
fileLogger.field("logFileName", logFile);
if (logFile.fileExists())
logFile.file_Delete();
var projectCollection = new ProjectCollection();
var project = projectCollection.LoadProject(projectFile);
if (project.isNull())
{
"could not load project file: {0}".error(projectFile);
return false;
}
if (redirectToConsole)
projectCollection.RegisterLogger(new ConsoleLogger());
projectCollection.RegisterLogger(fileLogger);
var result = project.Build();
fileLogger.Shutdown();
return result;
}
catch(Exception ex)
{
ex.log();
return false;
}
}
public static string createProjectFile_and_Build(this string projectName, string sourceFile, string pathToAssemblies, string targetDir, List<string> extraEmbebbedResources, Action<List<string>> beforeAddingReferences = null, Action<List<string>> beforeEmbedingFiles = null)
{
var projectFile = projectName.createProjectFile(sourceFile, pathToAssemblies, targetDir, extraEmbebbedResources, beforeAddingReferences ,beforeEmbedingFiles);
var buildResult= projectFile.buildProject();
if (buildResult)
return targetDir.pathCombine("bin").pathCombine(projectName + ".exe");
return null;
}
public static string createProjectFile_and_Build(this string projectName, string sourceFile, string pathToAssemblies, string targetDir, List<string> extraEmbebbedResources, Panel panel)
{
var createdExe = projectName.createProjectFile_and_Build(sourceFile, pathToAssemblies, targetDir, extraEmbebbedResources);
panel.showProjectBuildResult(projectName, targetDir, createdExe.valid());
return createdExe;
}
public static TextBox showProjectBuildResult(this Control panel , string projectName , string targetDir, bool buildOk)
{
var logFile = targetDir.pathCombine(projectName + ".csproj.log");
return panel.clear().add_TextArea().wordWrap(false).set_Text(logFile.fileContents())
.backColor(buildOk ? Color.LightGreen
: Color.LightPink);
}
public static T add_MenuItem_with_TestScripts<T>(this T control, Action<string> onItemSelected)
where T : Control
{
control .add_ContextMenu()
.add_MenuItem("Test with: LogViewer" , true, ()=> onItemSelected("Util - LogViewer.h2"))
.add_MenuItem("Test with: C# REPL Editor" , true, ()=> onItemSelected("Util - C# REPL Script [4.0].h2"))
.add_MenuItem("Test with: Package O2 Script into separate Folder" , true, ()=> onItemSelected("Util - Package O2 Script into separate Folder.h2"))
.add_MenuItem("Test with: HtmlAgilityPack - Filter Html Code" , true, ()=> onItemSelected("HtmlAgilityPack - Filter Html Code.h2"))
.add_MenuItem("View available Scripts" , true, ()=> "Util - O2 Available scripts.h2".executeFirstMethod());
return control;
}
public static string package_Script(this string scriptFile)
{
var compiledScript = "";
var pathToAssemblies = "";
var projectFile = "";
return scriptFile.package_Script(ref compiledScript, ref pathToAssemblies, ref projectFile);
}
public static string package_Script(this string scriptFile, ref string compiledScript, ref string pathToAssemblies, ref string projectFile, Action<List<string>> beforeAddingReferences = null, Action<List<string>> beforeEmbedingFiles = null)
{
compiledScript = scriptFile.compileScriptFile_into_SeparateFolder();
if (compiledScript.notNull())
{
pathToAssemblies = compiledScript.directoryName();
var buildFilesDir = pathToAssemblies.pathCombine("_BuildFiles").createDir();
//create wrapping exe using MicrosoftBuild
var projectName = scriptFile.fileName_WithoutExtension();
projectFile = buildFilesDir.pathCombine(projectName + ".csproj");
var sourceFile = "Program_UseWith_O2_CreatedExes.cs".local();
//add special folders
O2Setup.createEmbeddedFolder_Scripts(buildFilesDir)
.copyFileReferencesToEmbeddedFolder(scriptFile);;
O2Setup.createEmbeddedFolder_Data(buildFilesDir,projectName);
var extraEmbebbedResources = buildFilesDir.mapExtraEmbebbedResources(scriptFile);
extraEmbebbedResources.add(scriptFile.local()) // include original script as an embeded file
.add(sourceFile); // and file that created the exe
var createdExe = projectName.createProjectFile_and_Build(sourceFile, pathToAssemblies, buildFilesDir,extraEmbebbedResources,beforeAddingReferences, beforeEmbedingFiles);
if (createdExe.valid())
{
createdExe.file_WaitFor_CanOpen();
Files.deleteAllFilesFromDir(pathToAssemblies);
compiledScript = createdExe.file_Copy(pathToAssemblies);
compiledScript = createdExe.file_Copy(buildFilesDir); // for now also copy it to the buildFileDir
"CompiledScript: {0}".info(compiledScript);
return compiledScript;
}
}
return null;
}
}
}