diff options
Diffstat (limited to 'src/WixToolset.Core/Binder.cs')
-rw-r--r-- | src/WixToolset.Core/Binder.cs | 451 |
1 files changed, 55 insertions, 396 deletions
diff --git a/src/WixToolset.Core/Binder.cs b/src/WixToolset.Core/Binder.cs index 2369b600..9db27fec 100644 --- a/src/WixToolset.Core/Binder.cs +++ b/src/WixToolset.Core/Binder.cs | |||
@@ -3,14 +3,11 @@ | |||
3 | namespace WixToolset.Core | 3 | namespace WixToolset.Core |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections; | ||
7 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
8 | using System.Diagnostics; | 7 | using System.Diagnostics; |
9 | using System.Globalization; | ||
10 | using System.IO; | 8 | using System.IO; |
11 | using System.Linq; | 9 | using System.Linq; |
12 | using System.Reflection; | 10 | using System.Reflection; |
13 | using WixToolset.Bind; | ||
14 | using WixToolset.Core.Bind; | 11 | using WixToolset.Core.Bind; |
15 | using WixToolset.Data; | 12 | using WixToolset.Data; |
16 | using WixToolset.Data.Bind; | 13 | using WixToolset.Data.Bind; |
@@ -148,130 +145,72 @@ namespace WixToolset.Core | |||
148 | /// <value>The Wix variable resolver.</value> | 145 | /// <value>The Wix variable resolver.</value> |
149 | internal WixVariableResolver WixVariableResolver { get; set; } | 146 | internal WixVariableResolver WixVariableResolver { get; set; } |
150 | 147 | ||
151 | /// <summary> | 148 | public BindResult Bind(IBindContext context) |
152 | /// Add a binder extension. | ||
153 | /// </summary> | ||
154 | /// <param name="extension">New extension.</param> | ||
155 | //public void AddExtension(IBinderExtension extension) | ||
156 | //{ | ||
157 | // this.extensions.Add(extension); | ||
158 | //} | ||
159 | |||
160 | /// <summary> | ||
161 | /// Add a file manager extension. | ||
162 | /// </summary> | ||
163 | /// <param name="extension">New file manager.</param> | ||
164 | //public void AddExtension(IBinderFileManager extension) | ||
165 | //{ | ||
166 | // this.fileManagers.Add(extension); | ||
167 | //} | ||
168 | |||
169 | public bool Bind(IBindContext context) | ||
170 | { | 149 | { |
171 | this.Context = context; | 150 | this.Context = context; |
172 | 151 | ||
173 | //if (!String.IsNullOrEmpty(this.Context.FileManagerCore.CabCachePath)) | ||
174 | //{ | ||
175 | // Directory.CreateDirectory(this.Context.FileManagerCore.CabCachePath); | ||
176 | //} | ||
177 | |||
178 | //this.core = new BinderCore(); | ||
179 | //this.core.FileManagerCore = this.Context.FileManagerCore; | ||
180 | |||
181 | this.WriteBuildInfoTable(this.Context.IntermediateRepresentation, this.Context.OutputPath); | 152 | this.WriteBuildInfoTable(this.Context.IntermediateRepresentation, this.Context.OutputPath); |
182 | 153 | ||
183 | // Prebind. | ||
184 | // | ||
185 | this.Context.Extensions = this.Context.ExtensionManager.Create<IBinderExtension>(); | ||
186 | |||
187 | foreach (IBinderExtension extension in this.Context.Extensions) | ||
188 | { | ||
189 | extension.PreBind(this.Context); | ||
190 | } | ||
191 | |||
192 | // Resolve. | ||
193 | // | ||
194 | var resolveResult = this.Resolve(); | ||
195 | |||
196 | this.Context.DelayedFields = resolveResult.DelayedFields; | ||
197 | |||
198 | this.Context.ExpectedEmbeddedFiles = resolveResult.ExpectedEmbeddedFiles; | ||
199 | |||
200 | // Backend. | ||
201 | // | ||
202 | var bindResult = this.BackendBind(); | 154 | var bindResult = this.BackendBind(); |
203 | 155 | return bindResult; | |
204 | if (bindResult != null) | ||
205 | { | ||
206 | // Postbind. | ||
207 | // | ||
208 | foreach (IBinderExtension extension in this.Context.Extensions) | ||
209 | { | ||
210 | extension.PostBind(bindResult); | ||
211 | } | ||
212 | |||
213 | // Layout. | ||
214 | // | ||
215 | this.Layout(bindResult); | ||
216 | } | ||
217 | |||
218 | return this.Context.Messaging.EncounteredError; | ||
219 | } | 156 | } |
220 | 157 | ||
221 | private ResolveResult Resolve() | 158 | //// private ResolveResult Resolve() |
222 | { | 159 | //// { |
223 | var buildingPatch = this.Context.IntermediateRepresentation.Sections.Any(s => s.Type == SectionType.Patch); | 160 | //// var buildingPatch = this.Context.IntermediateRepresentation.Sections.Any(s => s.Type == SectionType.Patch); |
224 | 161 | ||
225 | var filesWithEmbeddedFiles = new ExtractEmbeddedFiles(); | 162 | //// var filesWithEmbeddedFiles = new ExtractEmbeddedFiles(); |
226 | 163 | ||
227 | IEnumerable<DelayedField> delayedFields; | 164 | //// IEnumerable<DelayedField> delayedFields; |
228 | { | 165 | //// { |
229 | var command = new ResolveFieldsCommand(); | 166 | //// var command = new ResolveFieldsCommand(); |
230 | command.Messaging = this.Context.Messaging; | 167 | //// command.Messaging = this.Context.Messaging; |
231 | command.BuildingPatch = buildingPatch; | 168 | //// command.BuildingPatch = buildingPatch; |
232 | command.BindVariableResolver = this.Context.WixVariableResolver; | 169 | //// command.BindVariableResolver = this.Context.WixVariableResolver; |
233 | command.BindPaths = this.Context.BindPaths; | 170 | //// command.BindPaths = this.Context.BindPaths; |
234 | command.Extensions = this.Context.Extensions; | 171 | //// command.Extensions = this.Context.Extensions; |
235 | command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles; | 172 | //// command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles; |
236 | command.IntermediateFolder = this.Context.IntermediateFolder; | 173 | //// command.IntermediateFolder = this.Context.IntermediateFolder; |
237 | command.Intermediate = this.Context.IntermediateRepresentation; | 174 | //// command.Intermediate = this.Context.IntermediateRepresentation; |
238 | command.SupportDelayedResolution = true; | 175 | //// command.SupportDelayedResolution = true; |
239 | command.Execute(); | 176 | //// command.Execute(); |
240 | 177 | ||
241 | delayedFields = command.DelayedFields; | 178 | //// delayedFields = command.DelayedFields; |
242 | } | 179 | //// } |
243 | 180 | ||
244 | #if REVISIT_FOR_PATCHING | 181 | ////#if REVISIT_FOR_PATCHING |
245 | if (this.Context.IntermediateRepresentation.SubStorages != null) | 182 | //// if (this.Context.IntermediateRepresentation.SubStorages != null) |
246 | { | 183 | //// { |
247 | foreach (SubStorage transform in this.Context.IntermediateRepresentation.SubStorages) | 184 | //// foreach (SubStorage transform in this.Context.IntermediateRepresentation.SubStorages) |
248 | { | 185 | //// { |
249 | var command = new ResolveFieldsCommand(); | 186 | //// var command = new ResolveFieldsCommand(); |
250 | command.BuildingPatch = buildingPatch; | 187 | //// command.BuildingPatch = buildingPatch; |
251 | command.BindVariableResolver = this.Context.WixVariableResolver; | 188 | //// command.BindVariableResolver = this.Context.WixVariableResolver; |
252 | command.BindPaths = this.Context.BindPaths; | 189 | //// command.BindPaths = this.Context.BindPaths; |
253 | command.Extensions = this.Context.Extensions; | 190 | //// command.Extensions = this.Context.Extensions; |
254 | command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles; | 191 | //// command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles; |
255 | command.IntermediateFolder = this.Context.IntermediateFolder; | 192 | //// command.IntermediateFolder = this.Context.IntermediateFolder; |
256 | command.Intermediate = this.Context.IntermediateRepresentation; | 193 | //// command.Intermediate = this.Context.IntermediateRepresentation; |
257 | command.SupportDelayedResolution = false; | 194 | //// command.SupportDelayedResolution = false; |
258 | command.Execute(); | 195 | //// command.Execute(); |
259 | } | 196 | //// } |
260 | } | 197 | //// } |
261 | #endif | 198 | ////#endif |
262 | 199 | ||
263 | var expectedEmbeddedFiles = filesWithEmbeddedFiles.GetExpectedEmbeddedFiles(); | 200 | //// var expectedEmbeddedFiles = filesWithEmbeddedFiles.GetExpectedEmbeddedFiles(); |
264 | 201 | ||
265 | return new ResolveResult | 202 | //// return new ResolveResult |
266 | { | 203 | //// { |
267 | ExpectedEmbeddedFiles = expectedEmbeddedFiles, | 204 | //// ExpectedEmbeddedFiles = expectedEmbeddedFiles, |
268 | DelayedFields = delayedFields, | 205 | //// DelayedFields = delayedFields, |
269 | }; | 206 | //// }; |
270 | } | 207 | //// } |
271 | 208 | ||
272 | private BindResult BackendBind() | 209 | private BindResult BackendBind() |
273 | { | 210 | { |
274 | var backendFactories = this.Context.ExtensionManager.Create<IBackendFactory>(); | 211 | var extensionManager = this.Context.ServiceProvider.GetService<IExtensionManager>(); |
212 | |||
213 | var backendFactories = extensionManager.Create<IBackendFactory>(); | ||
275 | 214 | ||
276 | var entrySection = this.Context.IntermediateRepresentation.Sections[0]; | 215 | var entrySection = this.Context.IntermediateRepresentation.Sections[0]; |
277 | 216 | ||
@@ -289,31 +228,6 @@ namespace WixToolset.Core | |||
289 | return null; | 228 | return null; |
290 | } | 229 | } |
291 | 230 | ||
292 | private void Layout(BindResult result) | ||
293 | { | ||
294 | try | ||
295 | { | ||
296 | this.LayoutMedia(result.FileTransfers); | ||
297 | } | ||
298 | finally | ||
299 | { | ||
300 | if (!String.IsNullOrEmpty(this.Context.ContentsFile) && result.ContentFilePaths != null) | ||
301 | { | ||
302 | this.CreateContentsFile(this.Context.ContentsFile, result.ContentFilePaths); | ||
303 | } | ||
304 | |||
305 | if (!String.IsNullOrEmpty(this.Context.OutputsFile) && result.FileTransfers != null) | ||
306 | { | ||
307 | this.CreateOutputsFile(this.Context.OutputsFile, result.FileTransfers, this.Context.OutputPdbPath); | ||
308 | } | ||
309 | |||
310 | if (!String.IsNullOrEmpty(this.Context.BuiltOutputsFile) && result.FileTransfers != null) | ||
311 | { | ||
312 | this.CreateBuiltOutputsFile(this.Context.BuiltOutputsFile, result.FileTransfers, this.Context.OutputPdbPath); | ||
313 | } | ||
314 | } | ||
315 | } | ||
316 | |||
317 | /// <summary> | 231 | /// <summary> |
318 | /// Binds an output. | 232 | /// Binds an output. |
319 | /// </summary> | 233 | /// </summary> |
@@ -429,35 +343,6 @@ namespace WixToolset.Core | |||
429 | #endif | 343 | #endif |
430 | 344 | ||
431 | /// <summary> | 345 | /// <summary> |
432 | /// Does any housekeeping after Bind. | ||
433 | /// </summary> | ||
434 | /// <param name="tidy">Whether or not any actual tidying should be done.</param> | ||
435 | public void Cleanup(bool tidy) | ||
436 | { | ||
437 | if (tidy) | ||
438 | { | ||
439 | if (!this.DeleteTempFiles()) | ||
440 | { | ||
441 | this.Context.Messaging.Write(WarningMessages.FailedToDeleteTempDir(this.TempFilesLocation)); | ||
442 | } | ||
443 | } | ||
444 | else | ||
445 | { | ||
446 | this.Context.Messaging.Write(VerboseMessages.BinderTempDirLocatedAt(this.TempFilesLocation)); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | /// <summary> | ||
451 | /// Cleans up the temp files used by the Binder. | ||
452 | /// </summary> | ||
453 | /// <returns>True if all files were deleted, false otherwise.</returns> | ||
454 | private bool DeleteTempFiles() | ||
455 | { | ||
456 | bool deleted = Common.DeleteTempFiles(this.TempFilesLocation, this.Context.Messaging); | ||
457 | return deleted; | ||
458 | } | ||
459 | |||
460 | /// <summary> | ||
461 | /// Populates the WixBuildInfo table in an output. | 346 | /// Populates the WixBuildInfo table in an output. |
462 | /// </summary> | 347 | /// </summary> |
463 | /// <param name="output">The output.</param> | 348 | /// <param name="output">The output.</param> |
@@ -585,231 +470,5 @@ namespace WixToolset.Core | |||
585 | command.Execute(); | 470 | command.Execute(); |
586 | } | 471 | } |
587 | #endif | 472 | #endif |
588 | |||
589 | /// <summary> | ||
590 | /// Final step in binding that transfers (moves/copies) all files generated into the appropriate | ||
591 | /// location in the source image | ||
592 | /// </summary> | ||
593 | /// <param name="fileTransfers">List of files to transfer.</param> | ||
594 | private void LayoutMedia(IEnumerable<FileTransfer> transfers) | ||
595 | { | ||
596 | if (null != transfers && transfers.Any()) | ||
597 | { | ||
598 | this.Context.Messaging.Write(VerboseMessages.LayingOutMedia()); | ||
599 | |||
600 | var command = new TransferFilesCommand(this.Context.Messaging, this.Context.BindPaths, this.Context.Extensions, transfers, this.Context.SuppressAclReset); | ||
601 | command.Execute(); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | /// <summary> | ||
606 | /// Get the source path of a directory. | ||
607 | /// </summary> | ||
608 | /// <param name="directories">All cached directories.</param> | ||
609 | /// <param name="componentIdGenSeeds">Hash table of Component GUID generation seeds indexed by directory id.</param> | ||
610 | /// <param name="directory">Directory identifier.</param> | ||
611 | /// <param name="canonicalize">Canonicalize the path for standard directories.</param> | ||
612 | /// <returns>Source path of a directory.</returns> | ||
613 | public static string GetDirectoryPath(Dictionary<string, ResolvedDirectory> directories, Dictionary<string, string> componentIdGenSeeds, string directory, bool canonicalize) | ||
614 | { | ||
615 | if (!directories.ContainsKey(directory)) | ||
616 | { | ||
617 | throw new WixException(ErrorMessages.ExpectedDirectory(directory)); | ||
618 | } | ||
619 | |||
620 | ResolvedDirectory resolvedDirectory = (ResolvedDirectory)directories[directory]; | ||
621 | |||
622 | if (null == resolvedDirectory.Path) | ||
623 | { | ||
624 | if (null != componentIdGenSeeds && componentIdGenSeeds.ContainsKey(directory)) | ||
625 | { | ||
626 | resolvedDirectory.Path = (string)componentIdGenSeeds[directory]; | ||
627 | } | ||
628 | else if (canonicalize && WindowsInstallerStandard.IsStandardDirectory(directory)) | ||
629 | { | ||
630 | // when canonicalization is on, standard directories are treated equally | ||
631 | resolvedDirectory.Path = directory; | ||
632 | } | ||
633 | else | ||
634 | { | ||
635 | string name = resolvedDirectory.Name; | ||
636 | |||
637 | if (canonicalize && null != name) | ||
638 | { | ||
639 | name = name.ToLower(CultureInfo.InvariantCulture); | ||
640 | } | ||
641 | |||
642 | if (String.IsNullOrEmpty(resolvedDirectory.DirectoryParent)) | ||
643 | { | ||
644 | resolvedDirectory.Path = name; | ||
645 | } | ||
646 | else | ||
647 | { | ||
648 | string parentPath = GetDirectoryPath(directories, componentIdGenSeeds, resolvedDirectory.DirectoryParent, canonicalize); | ||
649 | |||
650 | if (null != resolvedDirectory.Name) | ||
651 | { | ||
652 | resolvedDirectory.Path = Path.Combine(parentPath, name); | ||
653 | } | ||
654 | else | ||
655 | { | ||
656 | resolvedDirectory.Path = parentPath; | ||
657 | } | ||
658 | } | ||
659 | } | ||
660 | } | ||
661 | |||
662 | return resolvedDirectory.Path; | ||
663 | } | ||
664 | |||
665 | /// <summary> | ||
666 | /// Gets the source path of a file. | ||
667 | /// </summary> | ||
668 | /// <param name="directories">All cached directories in <see cref="ResolvedDirectory"/>.</param> | ||
669 | /// <param name="directoryId">Parent directory identifier.</param> | ||
670 | /// <param name="fileName">File name (in long|source format).</param> | ||
671 | /// <param name="compressed">Specifies the package is compressed.</param> | ||
672 | /// <param name="useLongName">Specifies the package uses long file names.</param> | ||
673 | /// <returns>Source path of file relative to package directory.</returns> | ||
674 | public static string GetFileSourcePath(Dictionary<string, ResolvedDirectory> directories, string directoryId, string fileName, bool compressed, bool useLongName) | ||
675 | { | ||
676 | string fileSourcePath = Common.GetName(fileName, true, useLongName); | ||
677 | |||
678 | if (compressed) | ||
679 | { | ||
680 | // Use just the file name of the file since all uncompressed files must appear | ||
681 | // in the root of the image in a compressed package. | ||
682 | } | ||
683 | else | ||
684 | { | ||
685 | // Get the relative path of where we want the file to be layed out as specified | ||
686 | // in the Directory table. | ||
687 | string directoryPath = Binder.GetDirectoryPath(directories, null, directoryId, false); | ||
688 | fileSourcePath = Path.Combine(directoryPath, fileSourcePath); | ||
689 | } | ||
690 | |||
691 | // Strip off "SourceDir" if it's still on there. | ||
692 | if (fileSourcePath.StartsWith("SourceDir\\", StringComparison.Ordinal)) | ||
693 | { | ||
694 | fileSourcePath = fileSourcePath.Substring(10); | ||
695 | } | ||
696 | |||
697 | return fileSourcePath; | ||
698 | } | ||
699 | |||
700 | /// <summary> | ||
701 | /// Writes the paths to the content files included in the package to a text file. | ||
702 | /// </summary> | ||
703 | /// <param name="path">Path to write file.</param> | ||
704 | /// <param name="contentFilePaths">Collection of paths to content files that will be written to file.</param> | ||
705 | private void CreateContentsFile(string path, IEnumerable<string> contentFilePaths) | ||
706 | { | ||
707 | string directory = Path.GetDirectoryName(path); | ||
708 | if (!Directory.Exists(directory)) | ||
709 | { | ||
710 | Directory.CreateDirectory(directory); | ||
711 | } | ||
712 | |||
713 | using (StreamWriter contents = new StreamWriter(path, false)) | ||
714 | { | ||
715 | foreach (string contentPath in contentFilePaths) | ||
716 | { | ||
717 | contents.WriteLine(contentPath); | ||
718 | } | ||
719 | } | ||
720 | } | ||
721 | |||
722 | /// <summary> | ||
723 | /// Writes the paths to the content files included in the bundle to a text file. | ||
724 | /// </summary> | ||
725 | /// <param name="path">Path to write file.</param> | ||
726 | /// <param name="payloads">Collection of payloads whose source will be written to file.</param> | ||
727 | private void CreateContentsFile(string path, IEnumerable<WixBundlePayloadTuple> payloads) | ||
728 | { | ||
729 | string directory = Path.GetDirectoryName(path); | ||
730 | if (!Directory.Exists(directory)) | ||
731 | { | ||
732 | Directory.CreateDirectory(directory); | ||
733 | } | ||
734 | |||
735 | using (StreamWriter contents = new StreamWriter(path, false)) | ||
736 | { | ||
737 | foreach (var payload in payloads) | ||
738 | { | ||
739 | if (payload.ContentFile) | ||
740 | { | ||
741 | var fullPath = Path.GetFullPath(payload.SourceFile); | ||
742 | contents.WriteLine(fullPath); | ||
743 | } | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | |||
748 | /// <summary> | ||
749 | /// Writes the paths to the output files to a text file. | ||
750 | /// </summary> | ||
751 | /// <param name="path">Path to write file.</param> | ||
752 | /// <param name="fileTransfers">Collection of files that were transferred to the output directory.</param> | ||
753 | /// <param name="pdbPath">Optional path to created .wixpdb.</param> | ||
754 | private void CreateOutputsFile(string path, IEnumerable<FileTransfer> fileTransfers, string pdbPath) | ||
755 | { | ||
756 | string directory = Path.GetDirectoryName(path); | ||
757 | if (!Directory.Exists(directory)) | ||
758 | { | ||
759 | Directory.CreateDirectory(directory); | ||
760 | } | ||
761 | |||
762 | using (StreamWriter outputs = new StreamWriter(path, false)) | ||
763 | { | ||
764 | foreach (FileTransfer fileTransfer in fileTransfers) | ||
765 | { | ||
766 | // Don't list files where the source is the same as the destination since | ||
767 | // that might be the only place the file exists. The outputs file is often | ||
768 | // used to delete stuff and losing the original source would be bad. | ||
769 | if (!fileTransfer.Redundant) | ||
770 | { | ||
771 | outputs.WriteLine(fileTransfer.Destination); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | if (!String.IsNullOrEmpty(pdbPath)) | ||
776 | { | ||
777 | outputs.WriteLine(Path.GetFullPath(pdbPath)); | ||
778 | } | ||
779 | } | ||
780 | } | ||
781 | |||
782 | /// <summary> | ||
783 | /// Writes the paths to the built output files to a text file. | ||
784 | /// </summary> | ||
785 | /// <param name="path">Path to write file.</param> | ||
786 | /// <param name="fileTransfers">Collection of files that were transferred to the output directory.</param> | ||
787 | /// <param name="pdbPath">Optional path to created .wixpdb.</param> | ||
788 | private void CreateBuiltOutputsFile(string path, IEnumerable<FileTransfer> fileTransfers, string pdbPath) | ||
789 | { | ||
790 | string directory = Path.GetDirectoryName(path); | ||
791 | if (!Directory.Exists(directory)) | ||
792 | { | ||
793 | Directory.CreateDirectory(directory); | ||
794 | } | ||
795 | |||
796 | using (StreamWriter outputs = new StreamWriter(path, false)) | ||
797 | { | ||
798 | foreach (FileTransfer fileTransfer in fileTransfers) | ||
799 | { | ||
800 | // Only write the built file transfers. Also, skip redundant | ||
801 | // files for the same reason spelled out in this.CreateOutputsFile(). | ||
802 | if (fileTransfer.Built && !fileTransfer.Redundant) | ||
803 | { | ||
804 | outputs.WriteLine(fileTransfer.Destination); | ||
805 | } | ||
806 | } | ||
807 | |||
808 | if (!String.IsNullOrEmpty(pdbPath)) | ||
809 | { | ||
810 | outputs.WriteLine(Path.GetFullPath(pdbPath)); | ||
811 | } | ||
812 | } | ||
813 | } | ||
814 | } | 473 | } |
815 | } | 474 | } |