@@ -105,110 +105,135 @@ private void SaveHistoryAtExit()
105
105
WriteHistoryRange ( 0 , _history . Count - 1 , File . CreateText ) ;
106
106
}
107
107
108
- private void WriteHistoryRange ( int start , int end , Func < string , StreamWriter > fileOpener )
108
+
109
+ private int historyErrorReportedCount ;
110
+ private void ReportHistoryFileError ( Exception e )
111
+ {
112
+ if ( historyErrorReportedCount == 2 )
113
+ return ;
114
+
115
+ historyErrorReportedCount += 1 ;
116
+ var fgColor = Console . ForegroundColor ;
117
+ var bgColor = Console . BackgroundColor ;
118
+ Console . ForegroundColor = Options . ErrorForegroundColor ;
119
+ Console . WriteLine ( PSReadLineResources . HistoryFileErrorMessage , Options . HistorySavePath , e . Message ) ;
120
+ if ( historyErrorReportedCount == 2 )
121
+ {
122
+ Console . WriteLine ( PSReadLineResources . HistoryFileErrorFinalMessage ) ;
123
+ }
124
+ Console . ForegroundColor = fgColor ;
125
+ Console . BackgroundColor = bgColor ;
126
+ }
127
+
128
+ private bool WithHistoryFileMutexDo ( int timeout , Action action )
109
129
{
110
- if ( _historyFileMutex . WaitOne ( 100 ) )
130
+ if ( _historyFileMutex . WaitOne ( timeout ) )
111
131
{
112
132
try
113
133
{
114
- MaybeReadHistoryFile ( ) ;
134
+ action ( ) ;
135
+ }
136
+ catch ( UnauthorizedAccessException uae )
137
+ {
138
+ ReportHistoryFileError ( uae ) ;
139
+ return false ;
140
+ }
141
+ catch ( IOException ioe )
142
+ {
143
+ ReportHistoryFileError ( ioe ) ;
144
+ return false ;
145
+ }
146
+ finally
147
+ {
148
+ _historyFileMutex . ReleaseMutex ( ) ;
149
+ }
150
+ }
151
+
152
+ // No errors to report, so consider it a success even if we timed out on the mutex.
153
+ return true ;
154
+ }
115
155
116
- bool retry = true ;
156
+ private void WriteHistoryRange ( int start , int end , Func < string , StreamWriter > fileOpener )
157
+ {
158
+ WithHistoryFileMutexDo ( 100 , ( ) =>
159
+ {
160
+ if ( ! MaybeReadHistoryFile ( ) )
161
+ return ;
162
+
163
+ bool retry = true ;
117
164
retry_after_creating_directory :
118
- try
119
- {
120
- using ( var file = fileOpener ( Options . HistorySavePath ) )
121
- {
122
- for ( var i = start ; i <= end ; i ++ )
123
- {
124
- _history [ i ] . _saved = true ;
125
- var line = _history [ i ] . _line . Replace ( "\n " , "`\n " ) ;
126
- file . WriteLine ( line ) ;
127
- }
128
- }
129
- var fileInfo = new FileInfo ( Options . HistorySavePath ) ;
130
- _historyFileLastSavedSize = fileInfo . Length ;
131
- }
132
- catch ( DirectoryNotFoundException )
165
+ try
166
+ {
167
+ using ( var file = fileOpener ( Options . HistorySavePath ) )
133
168
{
134
- // Try making the directory, but just once
135
- if ( retry )
169
+ for ( var i = start ; i <= end ; i ++ )
136
170
{
137
- retry = false ;
138
- Directory . CreateDirectory ( Path . GetDirectoryName ( Options . HistorySavePath ) ) ;
139
- goto retry_after_creating_directory ;
171
+ _history [ i ] . _saved = true ;
172
+ var line = _history [ i ] . _line . Replace ( " \n " , "` \n " ) ;
173
+ file . WriteLine ( line ) ;
140
174
}
141
175
}
176
+ var fileInfo = new FileInfo ( Options . HistorySavePath ) ;
177
+ _historyFileLastSavedSize = fileInfo . Length ;
142
178
}
143
- finally
179
+ catch ( DirectoryNotFoundException )
144
180
{
145
- _historyFileMutex . ReleaseMutex ( ) ;
181
+ // Try making the directory, but just once
182
+ if ( retry )
183
+ {
184
+ retry = false ;
185
+ Directory . CreateDirectory ( Path . GetDirectoryName ( Options . HistorySavePath ) ) ;
186
+ goto retry_after_creating_directory ;
187
+ }
146
188
}
147
- }
189
+ } ) ;
148
190
}
149
191
150
- private void MaybeReadHistoryFile ( )
192
+ private bool MaybeReadHistoryFile ( )
151
193
{
152
194
if ( Options . HistorySaveStyle == HistorySaveStyle . SaveIncrementally )
153
195
{
154
- if ( _historyFileMutex . WaitOne ( 1000 ) )
196
+ return WithHistoryFileMutexDo ( 1000 , ( ) =>
155
197
{
156
- try
198
+ var fileInfo = new FileInfo ( Options . HistorySavePath ) ;
199
+ if ( fileInfo . Length != _historyFileLastSavedSize )
157
200
{
158
- try
201
+ var historyLines = new List < string > ( ) ;
202
+ using ( var fs = new FileStream ( Options . HistorySavePath , FileMode . Open ) )
203
+ using ( var sr = new StreamReader ( fs ) )
159
204
{
160
- var fileInfo = new FileInfo ( Options . HistorySavePath ) ;
161
- if ( fileInfo . Length != _historyFileLastSavedSize )
162
- {
163
- var historyLines = new List < string > ( ) ;
164
- using ( var fs = new FileStream ( Options . HistorySavePath , FileMode . Open ) )
165
- using ( var sr = new StreamReader ( fs ) )
166
- {
167
- fs . Seek ( _historyFileLastSavedSize , SeekOrigin . Begin ) ;
168
-
169
- while ( ! sr . EndOfStream )
170
- {
171
- historyLines . Add ( sr . ReadLine ( ) ) ;
172
- }
173
- }
174
- UpdateHistoryFromFile ( historyLines , fromDifferentSession : true ) ;
205
+ fs . Seek ( _historyFileLastSavedSize , SeekOrigin . Begin ) ;
175
206
176
- _historyFileLastSavedSize = fileInfo . Length ;
207
+ while ( ! sr . EndOfStream )
208
+ {
209
+ historyLines . Add ( sr . ReadLine ( ) ) ;
177
210
}
178
211
}
179
- catch ( FileNotFoundException )
180
- {
181
- }
182
- }
183
- finally
184
- {
185
- _historyFileMutex . ReleaseMutex ( ) ;
212
+ UpdateHistoryFromFile ( historyLines , fromDifferentSession : true ) ;
213
+
214
+ _historyFileLastSavedSize = fileInfo . Length ;
186
215
}
187
- }
216
+ } ) ;
188
217
}
218
+
219
+ // true means no errors, not that we actually read the file
220
+ return true ;
189
221
}
190
222
191
223
private void ReadHistoryFile ( )
192
224
{
193
- if ( _historyFileMutex . WaitOne ( 1000 ) )
225
+ WithHistoryFileMutexDo ( 1000 , ( ) =>
194
226
{
195
- try
227
+ if ( ! File . Exists ( Options . HistorySavePath ) )
196
228
{
197
- if ( ! File . Exists ( Options . HistorySavePath ) )
198
- {
199
- return ;
200
- }
201
-
202
- var historyLines = File . ReadAllLines ( Options . HistorySavePath ) ;
203
- UpdateHistoryFromFile ( historyLines , fromDifferentSession : false ) ;
204
- var fileInfo = new FileInfo ( Options . HistorySavePath ) ;
205
- _historyFileLastSavedSize = fileInfo . Length ;
206
- }
207
- finally
208
- {
209
- _historyFileMutex . ReleaseMutex ( ) ;
229
+ return ;
210
230
}
211
- }
231
+
232
+ var historyLines = File . ReadAllLines ( Options . HistorySavePath ) ;
233
+ UpdateHistoryFromFile ( historyLines , fromDifferentSession : false ) ;
234
+ var fileInfo = new FileInfo ( Options . HistorySavePath ) ;
235
+ _historyFileLastSavedSize = fileInfo . Length ;
236
+ } ) ;
212
237
}
213
238
214
239
void UpdateHistoryFromFile ( IEnumerable < string > historyLines , bool fromDifferentSession )
0 commit comments