aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.WindowsInstaller/Msi/View.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Msi/View.cs')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Msi/View.cs83
1 files changed, 79 insertions, 4 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Msi/View.cs b/src/WixToolset.Core.WindowsInstaller/Msi/View.cs
index 1beb72da..0fb7fc62 100644
--- a/src/WixToolset.Core.WindowsInstaller/Msi/View.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Msi/View.cs
@@ -3,6 +3,8 @@
3namespace WixToolset.Core.WindowsInstaller.Msi 3namespace WixToolset.Core.WindowsInstaller.Msi
4{ 4{
5 using System; 5 using System;
6 using System.Collections;
7 using System.Collections.Generic;
6 using System.Globalization; 8 using System.Globalization;
7 9
8 /// <summary> 10 /// <summary>
@@ -110,6 +112,11 @@ namespace WixToolset.Core.WindowsInstaller.Msi
110 } 112 }
111 113
112 /// <summary> 114 /// <summary>
115 /// Enumerator that automatically disposes of the retrieved Records.
116 /// </summary>
117 public IEnumerable<Record> Records => new ViewEnumerable(this);
118
119 /// <summary>
113 /// Executes a view with no customizable parameters. 120 /// Executes a view with no customizable parameters.
114 /// </summary> 121 /// </summary>
115 public void Execute() 122 public void Execute()
@@ -124,7 +131,7 @@ namespace WixToolset.Core.WindowsInstaller.Msi
124 /// <param name="record">Record containing parameters to be substituded into the view.</param> 131 /// <param name="record">Record containing parameters to be substituded into the view.</param>
125 public void Execute(Record record) 132 public void Execute(Record record)
126 { 133 {
127 int error = MsiInterop.MsiViewExecute(this.Handle, null == record ? 0 : record.Handle); 134 var error = MsiInterop.MsiViewExecute(this.Handle, null == record ? 0 : record.Handle);
128 if (0 != error) 135 if (0 != error)
129 { 136 {
130 throw new MsiException(error); 137 throw new MsiException(error);
@@ -137,9 +144,7 @@ namespace WixToolset.Core.WindowsInstaller.Msi
137 /// <returns>Returns the fetched record; otherwise null.</returns> 144 /// <returns>Returns the fetched record; otherwise null.</returns>
138 public Record Fetch() 145 public Record Fetch()
139 { 146 {
140 uint recordHandle; 147 var error = MsiInterop.MsiViewFetch(this.Handle, out var recordHandle);
141
142 int error = MsiInterop.MsiViewFetch(this.Handle, out recordHandle);
143 if (259 == error) 148 if (259 == error)
144 { 149 {
145 return null; 150 return null;
@@ -183,5 +188,75 @@ namespace WixToolset.Core.WindowsInstaller.Msi
183 188
184 return new Record(recordHandle); 189 return new Record(recordHandle);
185 } 190 }
191
192 private class ViewEnumerable : IEnumerable<Record>
193 {
194 private readonly View view;
195
196 public ViewEnumerable(View view) => this.view = view;
197
198 public IEnumerator<Record> GetEnumerator() => new ViewEnumerator(this.view);
199
200 IEnumerator IEnumerable.GetEnumerator() => new ViewEnumerator(this.view);
201 }
202
203 private class ViewEnumerator : IEnumerator<Record>
204 {
205 private readonly View view;
206 private readonly List<Record> records = new List<Record>();
207 private int position = -1;
208 private bool disposed;
209
210 public ViewEnumerator(View view) => this.view = view;
211
212 public Record Current => this.records[this.position];
213
214 object IEnumerator.Current => this.records[this.position];
215
216 public bool MoveNext()
217 {
218 if (this.position + 1 >= this.records.Count)
219 {
220 var record = this.view.Fetch();
221
222 if (record == null)
223 {
224 return false;
225 }
226
227 this.records.Add(record);
228 this.position = this.records.Count - 1;
229 }
230 else
231 {
232 ++this.position;
233 }
234
235 return true;
236 }
237
238 public void Reset() => this.position = -1;
239
240 public void Dispose()
241 {
242 this.Dispose(true);
243 }
244
245 protected virtual void Dispose(bool disposing)
246 {
247 if (!this.disposed)
248 {
249 if (disposing)
250 {
251 foreach (var record in this.records)
252 {
253 record.Dispose();
254 }
255 }
256
257 this.disposed = true;
258 }
259 }
260 }
186 } 261 }
187} 262}