diff options
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Msi/View.cs')
-rw-r--r-- | src/WixToolset.Core.WindowsInstaller/Msi/View.cs | 83 |
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 @@ | |||
3 | namespace WixToolset.Core.WindowsInstaller.Msi | 3 | namespace 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 | } |