Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit779c11b

Browse files
committed
added StartupManager to handle auto-start
changed order of CredentialManager loading
1 parentcd99645 commit779c11b

File tree

7 files changed

+120
-44
lines changed

7 files changed

+120
-44
lines changed

‎App/App.xaml.cs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,25 @@ public async Task ExitApplication()
138138
protectedoverridevoidOnLaunched(LaunchActivatedEventArgsargs)
139139
{
140140
_logger.LogInformation("new instance launched");
141+
142+
// Load the credentials in the background.
143+
varcredentialManagerCts=newCancellationTokenSource(TimeSpan.FromSeconds(15));
144+
varcredentialManager=_services.GetRequiredService<ICredentialManager>();
145+
credentialManager.LoadCredentials(credentialManagerCts.Token).ContinueWith(t=>
146+
{
147+
if(t.Exception!=null)
148+
{
149+
_logger.LogError(t.Exception,"failed to load credentials");
150+
#ifDEBUG
151+
Debug.WriteLine(t.Exception);
152+
Debugger.Break();
153+
#endif
154+
}
155+
156+
credentialManagerCts.Dispose();
157+
});
158+
159+
141160
// Start connecting to the manager in the background.
142161
varrpcController=_services.GetRequiredService<IRpcController>();
143162
if(rpcController.GetState().RpcLifecycle==RpcLifecycle.Disconnected)
@@ -155,7 +174,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs args)
155174
#endif
156175
}else
157176
{
158-
if(rpcController.GetState().RpcLifecycle==RpcLifecycle.Disconnected)
177+
if(rpcController.GetState().VpnLifecycle==VpnLifecycle.Stopped)
159178
{
160179
if(_settingsManager.Read(SettingsManager.ConnectOnLaunchKey,false))
161180
{
@@ -172,23 +191,6 @@ protected override void OnLaunched(LaunchActivatedEventArgs args)
172191
}
173192
});
174193

175-
// Load the credentials in the background.
176-
varcredentialManagerCts=newCancellationTokenSource(TimeSpan.FromSeconds(15));
177-
varcredentialManager=_services.GetRequiredService<ICredentialManager>();
178-
_=credentialManager.LoadCredentials(credentialManagerCts.Token).ContinueWith(t=>
179-
{
180-
if(t.Exception!=null)
181-
{
182-
_logger.LogError(t.Exception,"failed to load credentials");
183-
#ifDEBUG
184-
Debug.WriteLine(t.Exception);
185-
Debugger.Break();
186-
#endif
187-
}
188-
189-
credentialManagerCts.Dispose();
190-
},CancellationToken.None);
191-
192194
// Initialize file sync.
193195
varsyncSessionCts=newCancellationTokenSource(TimeSpan.FromSeconds(10));
194196
varsyncSessionController=_services.GetRequiredService<ISyncSessionController>();

‎App/Services/SettingsManager.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
usingSystem;
22
usingSystem.Collections.Generic;
33
usingSystem.IO;
4-
usingSystem.Linq;
5-
usingSystem.Text;
64
usingSystem.Text.Json;
7-
usingSystem.Threading.Tasks;
85

96
namespaceCoder.Desktop.App.Services;
107
/// <summary>

‎App/Services/StartupManager.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
usingMicrosoft.Win32;
2+
usingSystem;
3+
usingSystem.Diagnostics;
4+
usingSystem.Security;
5+
6+
namespaceCoder.Desktop.App.Services;
7+
publicstaticclassStartupManager
8+
{
9+
privateconststringRunKey=@"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
10+
privateconststringPoliciesExplorerUser=@"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
11+
privateconststringPoliciesExplorerMachine=@"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
12+
privateconststringDisableCurrentUserRun="DisableCurrentUserRun";
13+
privateconststringDisableLocalMachineRun="DisableLocalMachineRun";
14+
15+
privateconststring_defaultValueName="CoderDesktopApp";
16+
17+
/// <summary>
18+
/// Adds the current executable to the per‑user Run key. Returns <c>true</c> if successful.
19+
/// Fails (returns <c>false</c>) when blocked by policy or lack of permissions.
20+
/// </summary>
21+
publicstaticboolEnable()
22+
{
23+
if(IsDisabledByPolicy())
24+
returnfalse;
25+
26+
stringexe=Process.GetCurrentProcess().MainModule!.FileName;
27+
try
28+
{
29+
usingvarkey=Registry.CurrentUser.OpenSubKey(RunKey,writable:true)
30+
??Registry.CurrentUser.CreateSubKey(RunKey)!;
31+
key.SetValue(_defaultValueName,$"\"{exe}\"");
32+
returntrue;
33+
}
34+
catch(UnauthorizedAccessException){returnfalse;}
35+
catch(SecurityException){returnfalse;}
36+
}
37+
38+
/// <summary>Removes the value from the Run key (no-op if missing).</summary>
39+
publicstaticvoidDisable()
40+
{
41+
usingvarkey=Registry.CurrentUser.OpenSubKey(RunKey,writable:true);
42+
key?.DeleteValue(_defaultValueName,throwOnMissingValue:false);
43+
}
44+
45+
/// <summary>Checks whether the value exists in the Run key.</summary>
46+
publicstaticboolIsEnabled()
47+
{
48+
usingvarkey=Registry.CurrentUser.OpenSubKey(RunKey);
49+
returnkey?.GetValue(_defaultValueName)!=null;
50+
}
51+
52+
/// <summary>
53+
/// Detects whether group policy disables per‑user startup programs.
54+
/// Mirrors <see cref="Windows.ApplicationModel.StartupTaskState.DisabledByPolicy"/>.
55+
/// </summary>
56+
publicstaticboolIsDisabledByPolicy()
57+
{
58+
// User policy – HKCU
59+
using(varkeyUser=Registry.CurrentUser.OpenSubKey(PoliciesExplorerUser))
60+
{
61+
if((int?)keyUser?.GetValue(DisableCurrentUserRun)==1)returntrue;
62+
}
63+
// Machine policy – HKLM
64+
using(varkeyMachine=Registry.LocalMachine.OpenSubKey(PoliciesExplorerMachine))
65+
{
66+
if((int?)keyMachine?.GetValue(DisableLocalMachineRun)==1)returntrue;
67+
}
68+
69+
// Some non‑desktop SKUs report DisabledByPolicy implicitly
70+
returnfalse;
71+
}
72+
}
73+

‎App/ViewModels/SettingsViewModel.cs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
usingCoder.Desktop.App.Services;
22
usingCommunityToolkit.Mvvm.ComponentModel;
3-
usingCommunityToolkit.Mvvm.Input;
43
usingMicrosoft.Extensions.Logging;
54
usingMicrosoft.UI.Dispatching;
65
usingMicrosoft.UI.Xaml;
7-
usingMicrosoft.UI.Xaml.Controls;
86
usingSystem;
97

108
namespaceCoder.Desktop.App.ViewModels;
119

1210
publicpartialclassSettingsViewModel:ObservableObject
1311
{
14-
privateWindow?_window;
15-
privateDispatcherQueue?_dispatcherQueue;
16-
1712
privatereadonlyILogger<SettingsViewModel>_logger;
1813

1914
[ObservableProperty]
2015
publicpartialboolConnectOnLaunch{get;set;}=false;
2116

17+
[ObservableProperty]
18+
publicpartialboolStartOnLoginDisabled{get;set;}=false;
19+
2220
[ObservableProperty]
2321
publicpartialboolStartOnLogin{get;set;}=false;
2422

@@ -31,6 +29,10 @@ public SettingsViewModel(ILogger<SettingsViewModel> logger, ISettingsManager set
3129
ConnectOnLaunch=_settingsManager.Read(SettingsManager.ConnectOnLaunchKey,false);
3230
StartOnLogin=_settingsManager.Read(SettingsManager.StartOnLoginKey,false);
3331

32+
// Various policies can disable the "Start on login" option.
33+
// We disable the option in the UI if the policy is set.
34+
StartOnLoginDisabled=StartupManager.IsDisabledByPolicy();
35+
3436
this.PropertyChanged+=(_,args)=>
3537
{
3638
if(args.PropertyName==nameof(ConnectOnLaunch))
@@ -41,28 +43,34 @@ public SettingsViewModel(ILogger<SettingsViewModel> logger, ISettingsManager set
4143
}
4244
catch(Exceptionex)
4345
{
44-
Console.WriteLine($"Error saving{SettingsManager.ConnectOnLaunchKey} setting:{ex.Message}");
46+
_logger.LogError($"Error saving{SettingsManager.ConnectOnLaunchKey} setting:{ex.Message}");
4547
}
4648
}
4749
elseif(args.PropertyName==nameof(StartOnLogin))
4850
{
4951
try
5052
{
5153
_settingsManager.Save(SettingsManager.StartOnLoginKey,StartOnLogin);
54+
if(StartOnLogin)
55+
{
56+
StartupManager.Enable();
57+
}
58+
else
59+
{
60+
StartupManager.Disable();
61+
}
5262
}
5363
catch(Exceptionex)
5464
{
55-
Console.WriteLine($"Error saving{SettingsManager.StartOnLoginKey} setting:{ex.Message}");
65+
_logger.LogError($"Error saving{SettingsManager.StartOnLoginKey} setting:{ex.Message}");
5666
}
5767
}
5868
};
59-
}
6069

61-
publicvoidInitialize(Windowwindow,DispatcherQueuedispatcherQueue)
62-
{
63-
_window=window;
64-
_dispatcherQueue=dispatcherQueue;
65-
if(!_dispatcherQueue.HasThreadAccess)
66-
thrownewInvalidOperationException("Initialize must be called from the UI thread");
70+
// Ensure the StartOnLogin property matches the current startup state.
71+
if(StartOnLogin!=StartupManager.IsEnabled())
72+
{
73+
StartOnLogin=StartupManager.IsEnabled();
74+
}
6775
}
6876
}

‎App/Views/Pages/SettingsMainPage.xaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,16 @@
3939

4040
<controls:SettingsCardDescription="This setting controls whether the Coder Desktop app starts on Windows startup."
4141
Header="Start on login"
42-
HeaderIcon="{ui:FontIcon Glyph=&#xE819;}">
42+
HeaderIcon="{ui:FontIcon Glyph=&#xE819;}"
43+
IsEnabled="{x:Bind ViewModel.StartOnLoginDisabled, Converter={StaticResource InverseBoolConverter}, Mode=OneWay}">
4344
<ToggleSwitchIsOn="{x:Bind ViewModel.StartOnLogin, Mode=TwoWay}" />
4445
</controls:SettingsCard>
4546

4647
<TextBlockStyle="{StaticResource SettingsSectionHeaderTextBlockStyle}"Text="Coder Connect" />
47-
<controls:SettingsCardDescription="This setting controls whether Coder Connect automatically starts with Coder Desktop"
48+
<controls:SettingsCardDescription="This setting controls whether Coder Connect automatically starts with Coder Desktop."
4849
Header="Connect on launch"
49-
HeaderIcon="{ui:FontIcon Glyph=&#xE8AF;}">
50+
HeaderIcon="{ui:FontIcon Glyph=&#xE8AF;}"
51+
>
5052
<ToggleSwitchIsOn="{x:Bind ViewModel.ConnectOnLaunch, Mode=TwoWay}" />
5153
</controls:SettingsCard>
5254
</StackPanel>

‎App/Views/SettingsWindow.xaml.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ public SettingsWindow(SettingsViewModel viewModel)
1818

1919
SystemBackdrop=newDesktopAcrylicBackdrop();
2020

21-
ViewModel.Initialize(this,DispatcherQueue);
2221
RootFrame.Content=newSettingsMainPage(ViewModel);
2322

2423
this.CenterOnScreen();

‎Tests.App/Services/SettingsManagerTest.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
usingCoder.Desktop.App.Services;
2-
usingSystem;
3-
usingSystem.Collections.Generic;
4-
usingSystem.Linq;
5-
usingSystem.Text;
6-
usingSystem.Threading.Tasks;
72

83
namespaceCoder.Desktop.Tests.App.Services
94
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp