Skip to content

Commit e3422c6

Browse files
ResoDrive 0.3.3
1 parent 3edc099 commit e3422c6

13 files changed

Lines changed: 237 additions & 15 deletions

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## [0.3.3] - 2026-08-28
4+
5+
- Do not abort an upgrade when optional graceful-shutdown preparation fails.
6+
- Wait for path-matched installed processes to exit before replacing files.
7+
- Treat an already-stopped application as a successful installer no-op.
8+
- Include the MSI log path in failed application-update diagnostics.
9+
- Keep fixed header and footer actions aligned with scrollable content whenever
10+
a vertical scrollbar appears across the main pages and editor windows.
11+
312
## [0.3.2] - 2026-08-28
413

514
- Keep the per-user startup task registered when Windows normalizes its saved
@@ -28,6 +37,7 @@ First public preview of the cleaned ResoDrive codebase.
2837
- Install through a small setup bundle that downloads the .NET Desktop Runtime
2938
only when it is missing.
3039

40+
[0.3.3]: https://github.com/alphasixtyfive/resodrive/releases/tag/v0.3.3
3141
[0.3.2]: https://github.com/alphasixtyfive/resodrive/releases/tag/v0.3.2
3242
[0.3.1]: https://github.com/alphasixtyfive/resodrive/releases/tag/v0.3.1
3343
[0.3.0]: https://github.com/alphasixtyfive/resodrive/releases/tag/v0.3.0

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
1010
<Deterministic>true</Deterministic>
1111
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
12-
<VersionPrefix>0.3.2</VersionPrefix>
12+
<VersionPrefix>0.3.3</VersionPrefix>
1313
<ProductDisplayName>ResoDrive</ProductDisplayName>
1414
<ExecutableBaseName>resodrive</ExecutableBaseName>
1515
<ProductDescription>Mount Nextcloud, other WebDAV storage, and SFTP servers as drives in Windows</ProductDescription>

RELEASE_NOTES.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
ResoDrive 0.3.2 fixes Start with Windows registration on systems where Windows
2-
Task Scheduler normalizes the saved user identity and default privilege fields.
3-
ResoDrive now recognizes the normalized task as its own instead of removing it
4-
during post-registration verification.
1+
ResoDrive 0.3.3 fixes application updates that could stop with Windows Installer
2+
code 1603 when the optional graceful-shutdown preparation returned an error.
3+
Preparation is now best-effort; the installer always continues to a hidden,
4+
path-scoped fallback that stops only the installed ResoDrive processes and waits
5+
for them to exit before replacing files. An already-stopped application is now
6+
handled as a successful no-op instead of another installer error.
57

6-
Installer upgrades no longer open PowerShell windows while stopping the running
7-
application.
8+
Failed updates now include the exact installer-log path in their diagnostic
9+
message.
10+
11+
Fixed header and footer buttons now stay aligned with their scrollable content
12+
when a vertical scrollbar appears on Drives, Sync, Settings, setup, or an editor.
813

914
The normal download is `ResoDrive-Setup.exe`. Existing settings, credentials,
1015
mounts, and sync jobs are preserved during the upgrade.

installer/Package.wxs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@
9292
FileRef="ResoDriveExecutableFile"
9393
ExeCommand="--prepare-update"
9494
Execute="immediate"
95-
Return="check"
95+
Return="ignore"
9696
Impersonate="yes"
9797
/>
9898
<CustomAction
9999
Id="StopResoDriveForUpgrade"
100100
Directory="INSTALLFOLDER"
101-
ExeCommand="&quot;[System64Folder]WindowsPowerShell\v1.0\powershell.exe&quot; -NoP -NonI -WindowStyle Hidden -Command &quot;$p=(pwd).Path+'\resodrive.exe';gps resodrive -ea 0|? Path -eq $p|kill -Force -ea Stop&quot;"
101+
ExeCommand="&quot;[System64Folder]WindowsPowerShell\v1.0\powershell.exe&quot; -NoP -NonI -WindowStyle Hidden -Command &quot;$p=(pwd).Path+'\resodrive.exe';gps resodrive -ea 0|? Path -eq $p|%{kill $_ -Force -ea Stop;$_.WaitForExit()};exit 0&quot;"
102102
Execute="immediate"
103103
Return="check"
104104
Impersonate="no"
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
using System.Windows.Media;
4+
5+
namespace ResoDrive.App.Controls;
6+
7+
public sealed class ScrollBarGutter : FrameworkElement
8+
{
9+
public static readonly DependencyProperty ScrollOwnerProperty = DependencyProperty.Register(
10+
nameof(ScrollOwner),
11+
typeof(FrameworkElement),
12+
typeof(ScrollBarGutter),
13+
new PropertyMetadata(null, OnScrollOwnerChanged));
14+
15+
private ScrollViewer? _scrollViewer;
16+
17+
public ScrollBarGutter()
18+
{
19+
IsHitTestVisible = false;
20+
Loaded += OnLoaded;
21+
Unloaded += OnUnloaded;
22+
}
23+
24+
public FrameworkElement? ScrollOwner
25+
{
26+
get => (FrameworkElement?)GetValue(ScrollOwnerProperty);
27+
set => SetValue(ScrollOwnerProperty, value);
28+
}
29+
30+
private static void OnScrollOwnerChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
31+
{
32+
var gutter = (ScrollBarGutter)dependencyObject;
33+
gutter._scrollViewer = null;
34+
gutter.UpdateWidth();
35+
}
36+
37+
private void OnLoaded(object sender, RoutedEventArgs args)
38+
{
39+
LayoutUpdated += OnLayoutUpdated;
40+
UpdateWidth();
41+
}
42+
43+
private void OnUnloaded(object sender, RoutedEventArgs args)
44+
{
45+
LayoutUpdated -= OnLayoutUpdated;
46+
_scrollViewer = null;
47+
}
48+
49+
private void OnLayoutUpdated(object? sender, EventArgs args) => UpdateWidth();
50+
51+
private void UpdateWidth()
52+
{
53+
_scrollViewer ??= ScrollOwner as ScrollViewer ?? FindScrollViewer(ScrollOwner);
54+
var width = GetVisibleScrollBarWidth(_scrollViewer);
55+
56+
if (!Width.Equals(width))
57+
{
58+
Width = width;
59+
}
60+
}
61+
62+
private static double GetVisibleScrollBarWidth(ScrollViewer? scrollViewer)
63+
{
64+
if (scrollViewer?.ComputedVerticalScrollBarVisibility != Visibility.Visible)
65+
{
66+
return 0d;
67+
}
68+
69+
var scrollBar = scrollViewer.Template.FindName("PART_VerticalScrollBar", scrollViewer)
70+
as System.Windows.Controls.Primitives.ScrollBar;
71+
return scrollBar is not null && scrollBar.ActualWidth > 0d
72+
? scrollBar.ActualWidth
73+
: SystemParameters.VerticalScrollBarWidth;
74+
}
75+
76+
private static ScrollViewer? FindScrollViewer(DependencyObject? parent)
77+
{
78+
if (parent is null)
79+
{
80+
return null;
81+
}
82+
83+
for (var index = 0; index < VisualTreeHelper.GetChildrenCount(parent); index++)
84+
{
85+
var child = VisualTreeHelper.GetChild(parent, index);
86+
if (child is ScrollViewer scrollViewer)
87+
{
88+
return scrollViewer;
89+
}
90+
91+
var descendant = FindScrollViewer(child);
92+
if (descendant is not null)
93+
{
94+
return descendant;
95+
}
96+
}
97+
98+
return null;
99+
}
100+
}

src/ResoDrive.App/Infrastructure/ApplicationUpdateHandoff.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ await runtime.WaitForParentExitAsync(request.ParentProcessId, cancellationToken)
234234
cancellationToken)
235235
.ConfigureAwait(false);
236236
(status, message) = ClassifyInstallerExitCode(installerExitCode.Value);
237+
if (status == "failed")
238+
{
239+
message += " See the installer log at " +
240+
Path.ChangeExtension(request.InstallerPath, ".msi.log") + ".";
241+
}
237242
}
238243
catch (Win32Exception exception) when (exception.NativeErrorCode == ErrorCancelled)
239244
{

src/ResoDrive.App/MainWindow.xaml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
55
xmlns:local="clr-namespace:ResoDrive.App"
6+
xmlns:controls="clr-namespace:ResoDrive.App.Controls"
67
Title="{x:Static local:ProductInfo.Name}"
78
Width="920"
89
Height="610"
@@ -181,6 +182,7 @@
181182
<Grid.ColumnDefinitions>
182183
<ColumnDefinition Width="*" />
183184
<ColumnDefinition Width="Auto" />
185+
<ColumnDefinition Width="Auto" />
184186
</Grid.ColumnDefinitions>
185187
<StackPanel>
186188
<TextBlock Style="{StaticResource Title}" Text="Drives" />
@@ -207,8 +209,9 @@
207209
</StackPanel>
208210
</Button>
209211
</StackPanel>
212+
<controls:ScrollBarGutter Grid.Column="2" ScrollOwner="{Binding ElementName=MountRows}" />
210213
</Grid>
211-
<ListBox Grid.Row="1" Style="{StaticResource Rows}" ItemsSource="{Binding Mounts}">
214+
<ListBox x:Name="MountRows" Grid.Row="1" Style="{StaticResource Rows}" ItemsSource="{Binding Mounts}">
212215
<ListBox.ItemTemplate>
213216
<DataTemplate DataType="{x:Type local:MountRow}">
214217
<Border
@@ -305,20 +308,26 @@
305308
<RowDefinition Height="*" />
306309
</Grid.RowDefinitions>
307310
<Grid>
311+
<Grid.ColumnDefinitions>
312+
<ColumnDefinition Width="*" />
313+
<ColumnDefinition Width="Auto" />
314+
<ColumnDefinition Width="Auto" />
315+
</Grid.ColumnDefinitions>
308316
<StackPanel>
309317
<TextBlock Style="{StaticResource Title}" Text="Sync" />
310318
<TextBlock Style="{StaticResource Subtitle}" Text="{Binding JobSummary}" />
311319
</StackPanel>
312-
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,4,0">
320+
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,4,0">
313321
<Button Style="{StaticResource AccentButton}" Click="NewJob_Click" AutomationProperties.Name="Create sync job">
314322
<StackPanel Orientation="Horizontal">
315323
<TextBlock Style="{StaticResource InlineButtonGlyph}" Text="&#xE710;" />
316324
<TextBlock Text="New job" VerticalAlignment="Center" />
317325
</StackPanel>
318326
</Button>
319327
</StackPanel>
328+
<controls:ScrollBarGutter Grid.Column="2" ScrollOwner="{Binding ElementName=JobRows}" />
320329
</Grid>
321-
<ListBox Grid.Row="1" Style="{StaticResource Rows}" ItemsSource="{Binding Jobs}">
330+
<ListBox x:Name="JobRows" Grid.Row="1" Style="{StaticResource Rows}" ItemsSource="{Binding Jobs}">
322331
<ListBox.ItemTemplate>
323332
<DataTemplate DataType="{x:Type local:SyncRow}">
324333
<Border Style="{StaticResource RowCard}" MinHeight="58" AutomationProperties.Name="{Binding DetailText}">
@@ -411,6 +420,7 @@
411420
<Grid.ColumnDefinitions>
412421
<ColumnDefinition Width="*" />
413422
<ColumnDefinition Width="Auto" />
423+
<ColumnDefinition Width="Auto" />
414424
</Grid.ColumnDefinitions>
415425
<StackPanel>
416426
<TextBlock Style="{StaticResource Title}" Text="Log" />
@@ -498,6 +508,7 @@
498508
<Grid.ColumnDefinitions>
499509
<ColumnDefinition Width="*" />
500510
<ColumnDefinition Width="Auto" />
511+
<ColumnDefinition Width="Auto" />
501512
</Grid.ColumnDefinitions>
502513
<StackPanel>
503514
<TextBlock Style="{StaticResource Title}" Text="Settings" />
@@ -517,8 +528,9 @@
517528
<TextBlock Text="About" VerticalAlignment="Center" />
518529
</StackPanel>
519530
</Button>
531+
<controls:ScrollBarGutter Grid.Column="2" ScrollOwner="{Binding ElementName=SettingsScrollViewer}" />
520532
</Grid>
521-
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
533+
<ScrollViewer x:Name="SettingsScrollViewer" Grid.Row="1" VerticalScrollBarVisibility="Auto">
522534
<StackPanel Margin="0,0,4,0">
523535
<Border Style="{StaticResource Card}" Padding="16,12" Margin="0,0,0,10">
524536
<StackPanel>

src/ResoDrive.App/MountEditorWindow.xaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
55
xmlns:local="clr-namespace:ResoDrive.App"
6+
xmlns:controls="clr-namespace:ResoDrive.App.Controls"
67
Title="Drive settings"
78
Width="520"
89
Height="540"
@@ -31,6 +32,7 @@
3132
</StackPanel>
3233

3334
<ScrollViewer
35+
x:Name="EditorScrollViewer"
3436
Grid.Row="1"
3537
VerticalScrollBarVisibility="Auto"
3638
HorizontalScrollBarVisibility="Disabled"
@@ -182,6 +184,11 @@
182184
</ScrollViewer>
183185

184186
<Grid Grid.Row="2" Margin="0,14,0,0">
187+
<Grid.ColumnDefinitions>
188+
<ColumnDefinition Width="*" />
189+
<ColumnDefinition Width="Auto" />
190+
<ColumnDefinition Width="Auto" />
191+
</Grid.ColumnDefinitions>
185192
<Button
186193
x:Name="DeleteButton"
187194
Style="{StaticResource DangerButton}"
@@ -194,7 +201,7 @@
194201
<TextBlock Text="Delete" VerticalAlignment="Center" />
195202
</StackPanel>
196203
</Button>
197-
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
204+
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
198205
<Button
199206
Style="{StaticResource ButtonStyle}"
200207
Content="Cancel"
@@ -209,6 +216,7 @@
209216
Click="Save_Click"
210217
/>
211218
</StackPanel>
219+
<controls:ScrollBarGutter Grid.Column="2" ScrollOwner="{Binding ElementName=EditorScrollViewer}" />
212220
</Grid>
213221
</Grid>
214222
</Window>

src/ResoDrive.App/SetupWindow.xaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
55
xmlns:local="clr-namespace:ResoDrive.App"
6+
xmlns:controls="clr-namespace:ResoDrive.App.Controls"
67
Title="Add drive"
78
Width="660"
89
Height="690"
@@ -50,6 +51,7 @@
5051
hidden at the normal window size and prevents nested scrollbars when
5152
profiles are added or the available work area is unusually small. -->
5253
<ScrollViewer
54+
x:Name="SetupScrollViewer"
5355
Grid.Row="1"
5456
VerticalScrollBarVisibility="Auto"
5557
HorizontalScrollBarVisibility="Disabled"
@@ -284,6 +286,7 @@
284286
<Grid.ColumnDefinitions>
285287
<ColumnDefinition Width="*" />
286288
<ColumnDefinition Width="Auto" />
289+
<ColumnDefinition Width="Auto" />
287290
</Grid.ColumnDefinitions>
288291
<TextBlock
289292
x:Name="StatusText"
@@ -312,6 +315,7 @@
312315
Click="Connect_Click"
313316
/>
314317
</StackPanel>
318+
<controls:ScrollBarGutter Grid.Column="2" ScrollOwner="{Binding ElementName=SetupScrollViewer}" />
315319
</Grid>
316320
</Grid>
317321
</Window>

src/ResoDrive.App/SyncEditorWindow.xaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
55
xmlns:local="clr-namespace:ResoDrive.App"
6+
xmlns:controls="clr-namespace:ResoDrive.App.Controls"
67
Title="Sync settings"
78
Width="540"
89
Height="590"
@@ -30,6 +31,7 @@
3031
</StackPanel>
3132

3233
<ScrollViewer
34+
x:Name="EditorScrollViewer"
3335
Grid.Row="1"
3436
VerticalScrollBarVisibility="Auto"
3537
HorizontalScrollBarVisibility="Disabled"
@@ -212,6 +214,11 @@
212214
</ScrollViewer>
213215

214216
<Grid Grid.Row="2" Margin="0,14,0,0">
217+
<Grid.ColumnDefinitions>
218+
<ColumnDefinition Width="*" />
219+
<ColumnDefinition Width="Auto" />
220+
<ColumnDefinition Width="Auto" />
221+
</Grid.ColumnDefinitions>
215222
<Button
216223
x:Name="DeleteButton"
217224
Style="{StaticResource DangerButton}"
@@ -224,7 +231,7 @@
224231
<TextBlock Text="Delete" VerticalAlignment="Center" />
225232
</StackPanel>
226233
</Button>
227-
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
234+
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
228235
<Button
229236
Style="{StaticResource ButtonStyle}"
230237
Content="Cancel"
@@ -238,6 +245,7 @@
238245
Click="Save_Click"
239246
/>
240247
</StackPanel>
248+
<controls:ScrollBarGutter Grid.Column="2" ScrollOwner="{Binding ElementName=EditorScrollViewer}" />
241249
</Grid>
242250
</Grid>
243251
</Window>

0 commit comments

Comments
 (0)