Conversation
ruattd
left a comment
There was a problem hiding this comment.
- 用基于 RPC 的 LifecycleCommandHandler 而不是自己处理参数,申请管理员的特性把 PromoteService 改造一下复用已存在的权限,另外注意改权限不要影响其他线程
- 不要在 Essentials 里面新建文件夹了,以及这种非核心服务不适合丢这里(考虑在 App 里面加一个 Tools?
- 这点东西怎么能造出来 3 个文件的
- 有一吨无意义的更改,你是不是应该考虑丢掉 VS 这个垃圾
|
3: 一个类型一个文件 qwq |
|
LifeCycleCommandHandler 会通过 RPC 把调用传回原程序(没权限),这对吗😰 |
|
这对的,应该在原程序里面走线程提权并复用,而不是每次都现场跟用户申请权限 |
|
@ruattd MemSwap 暂时先这样,等 LifecycleCommandHandler 优化好了后面再改吧 |
Reviewer's Guide将内存优化(mem-swap)功能重构为一个独立的生命周期服务,提供正确的权限处理和管理员提权逻辑;用可复用的 C# helper 替换临时 interop 代码;统一人类可读的大小格式化实现,并修复工具页与核心工具类中的若干小 bug 和样式问题。 从 UI 触发的更新后 mem swap 流程时序图sequenceDiagram
actor User
participant PageToolsTest
participant ProcessInterop
participant ElevatedPCL as PCL_Process_admin
participant MemSwapService_elev as MemSwapService_admin
participant KernelInterop
participant Context
User->>PageToolsTest: ClickMemoryOptimizeButton
PageToolsTest->>PageToolsTest: AskTrulyWantMemoryOptimize()
PageToolsTest->>PageToolsTest: Check ProcessInterop.IsAdmin()
alt HasAdmin
PageToolsTest->>MemSwapService_elev: AcquirePrivileges()
PageToolsTest->>MemSwapService_elev: MemorySwap()
MemSwapService_elev->>SwapWorks: Execute swap operations
SwapWorks-->>MemSwapService_elev: Completed
MemSwapService_elev-->>PageToolsTest: true or false
PageToolsTest->>KernelInterop: GetAvailablePhysicalMemoryBytes()
KernelInterop-->>PageToolsTest: MemAfter
PageToolsTest->>User: Show result hint
else NoAdmin
PageToolsTest->>ProcessInterop: Start(Basics.ExecutablePath, "memory", runAsAdmin true)
ProcessInterop->>ElevatedPCL: Launch with UseShellExecute and verb runas
ElevatedPCL->>MemSwapService_elev: Initialize lifecycle services
MemSwapService_elev->>MemSwapService_elev: _CheckRequest()
MemSwapService_elev->>MemSwapService_elev: Check Basics.CommandLineArguments == ["memory"]
MemSwapService_elev->>ProcessInterop: IsAdmin()
alt ElevatedHasAdmin
MemSwapService_elev->>KernelInterop: GetPhysicalMemoryBytes().Available before
MemSwapService_elev->>MemSwapService_elev: AcquirePrivileges()
MemSwapService_elev->>MemSwapService_elev: MemorySwap(SwapScope.All)
MemSwapService_elev->>SwapWorks: Execute swap operations
SwapWorks-->>MemSwapService_elev: Completed
MemSwapService_elev->>KernelInterop: GetPhysicalMemoryBytes().Available after
MemSwapService_elev->>Context: RequestExit(diffInKB)
else ElevatedNoAdmin
MemSwapService_elev->>Context: Error("缺少管理员权限")
MemSwapService_elev->>Context: RequestExit(-1)
end
ElevatedPCL-->>PageToolsTest: Process exit code
PageToolsTest->>PageToolsTest: num = ExitCode * 1024
PageToolsTest->>User: Show result hint if num > 1024L
end
MemSwapService.MemorySwap 与 SwapWorks 的时序图sequenceDiagram
participant Caller as MemSwapService
participant MemSwapService
participant ProcessInterop
participant SwapWorks
participant NtInterop
Caller->>MemSwapService: MemorySwap(scope)
MemSwapService->>MemSwapService: _memSwapLock.Wait(0)
alt LockBusy
MemSwapService-->>Caller: false
else LockAcquired
MemSwapService->>ProcessInterop: IsAdmin()
alt NotAdmin
MemSwapService-->>Caller: false
else IsAdmin
MemSwapService->>MemSwapService: Check flags in scope
opt EmptyWorkingSets
MemSwapService->>SwapWorks: EmptyWorkingSets()
SwapWorks->>NtInterop: SetSystemInformation(SystemMemoryListInformation, 2)
end
opt FlushFileCache
MemSwapService->>SwapWorks: FlushFileCache()
SwapWorks->>NtInterop: SetSystemInformation(SystemFileCacheInformationEx, SYSTEM_FILECACHE_INFORMATION)
end
opt FlushModifiedList
MemSwapService->>SwapWorks: FlushModifiedList()
SwapWorks->>NtInterop: SetSystemInformation(SystemMemoryListInformation, 3)
end
opt PurgeStandbyList
MemSwapService->>SwapWorks: PurgeStandbyList()
SwapWorks->>NtInterop: SetSystemInformation(SystemMemoryListInformation, 4)
end
opt PurgeLowPriorityStandbyList
MemSwapService->>SwapWorks: PurgeLowPriorityStandbyList()
SwapWorks->>NtInterop: SetSystemInformation(SystemMemoryListInformation, 5)
end
opt RegistryReconciliation
MemSwapService->>SwapWorks: RegistryReconciliation()
SwapWorks->>NtInterop: SetSystemInformation(SystemRegistryReconciliationInformation, 0)
end
opt CombinePhysicalMemory
MemSwapService->>SwapWorks: CombinePhysicalMemory()
SwapWorks->>NtInterop: SetSystemInformation(SystemCombinePhysicalMemoryInformation, MEMORY_COMBINE_INFORMATION_EX)
end
MemSwapService-->>Caller: true
end
MemSwapService->>MemSwapService: _memSwapLock.Release()
end
更新后的 mem swap 与 IO 工具类图classDiagram
class MemSwapService {
<<sealed>>
- static SemaphoreSlim _memSwapLock
+ static void AcquirePrivileges()
+ static bool MemorySwap(SwapScope scope)
- static void _CheckRequest()
}
class SwapWorks {
<<static>>
- static void _ExecuteMemoryListOperation(int infoValue)
- static void _ExecuteStructureOperation~T~(T structure, NtInterop.SystemInformationClass infoClass)
+ static void EmptyWorkingSets()
+ static void FlushFileCache()
+ static void FlushModifiedList()
+ static void PurgeStandbyList()
+ static void PurgeLowPriorityStandbyList()
+ static void RegistryReconciliation()
+ static void CombinePhysicalMemory()
}
class SwapScope {
<<enum>>
None
EmptyWorkingSets
FlushFileCache
FlushModifiedList
PurgeStandbyList
PurgeLowPriorityStandbyList
RegistryReconciliation
CombinePhysicalMemory
All
}
class ByteStream {
- Stream BaseStream
+ long Length
+ ByteStream(Stream stream)
+ int Read(byte[] buffer, int offset, int count)
+ void Write(byte[] buffer, int offset, int count)
+ long Seek(long offset, SeekOrigin origin)
+ void Flush()
+ long Position
+ void Close()
+ string GetReadableLength()
- static string[] _Units
+ static string GetReadableLength(long length, int startUnit)
}
class ModBase {
<<module>>
+ string GetString(long FileSize)
}
class ProcessInterop {
<<static>>
+ bool IsAdmin()
+ Process Start(string path, string arguments, bool runAsAdmin)
}
class NtInterop {
<<static>>
+ void SetPrivilege(SePrivilege privilege, bool enable, bool thread)
+ void SetSystemInformation(SystemInformationClass infoClass, IntPtr info, uint length)
}
class KernelInterop {
<<static>>
+ PhysicalMemoryInfo GetPhysicalMemoryBytes()
+ ulong GetAvailablePhysicalMemoryBytes()
}
class Context {
<<static>>
+ void Info(string message)
+ void Warn(string message)
+ void Error(string message)
+ void Error(string message, Exception ex)
+ void RequestExit(int code)
}
ModBase ..> ByteStream : uses
MemSwapService ..> SwapScope : uses
MemSwapService ..> SwapWorks : uses
MemSwapService ..> NtInterop : uses
MemSwapService ..> KernelInterop : uses
MemSwapService ..> ProcessInterop : uses
MemSwapService ..> ByteStream : uses
MemSwapService ..> Context : uses
SwapWorks ..> NtInterop : uses
ProcessInterop ..> SystemDiagnosticsProcess : wraps
class SystemDiagnosticsProcess {
<<framework>>
}
文件级变更
可能关联的问题
Tips and commandsInteracting with Sourcery
Customizing Your Experience打开你的 dashboard 以便:
Getting HelpOriginal review guide in EnglishReviewer's GuideRefactors the memory optimization (mem-swap) feature into a dedicated lifecycle service with proper privilege handling and admin elevation, replaces ad‑hoc interop code with reusable C# helpers, unifies human‑readable size formatting, and fixes several smaller bugs and style issues in the tools page and core utilities. Sequence diagram for the updated mem swap flow from UIsequenceDiagram
actor User
participant PageToolsTest
participant ProcessInterop
participant ElevatedPCL as PCL_Process_admin
participant MemSwapService_elev as MemSwapService_admin
participant KernelInterop
participant Context
User->>PageToolsTest: ClickMemoryOptimizeButton
PageToolsTest->>PageToolsTest: AskTrulyWantMemoryOptimize()
PageToolsTest->>PageToolsTest: Check ProcessInterop.IsAdmin()
alt HasAdmin
PageToolsTest->>MemSwapService_elev: AcquirePrivileges()
PageToolsTest->>MemSwapService_elev: MemorySwap()
MemSwapService_elev->>SwapWorks: Execute swap operations
SwapWorks-->>MemSwapService_elev: Completed
MemSwapService_elev-->>PageToolsTest: true or false
PageToolsTest->>KernelInterop: GetAvailablePhysicalMemoryBytes()
KernelInterop-->>PageToolsTest: MemAfter
PageToolsTest->>User: Show result hint
else NoAdmin
PageToolsTest->>ProcessInterop: Start(Basics.ExecutablePath, "memory", runAsAdmin true)
ProcessInterop->>ElevatedPCL: Launch with UseShellExecute and verb runas
ElevatedPCL->>MemSwapService_elev: Initialize lifecycle services
MemSwapService_elev->>MemSwapService_elev: _CheckRequest()
MemSwapService_elev->>MemSwapService_elev: Check Basics.CommandLineArguments == ["memory"]
MemSwapService_elev->>ProcessInterop: IsAdmin()
alt ElevatedHasAdmin
MemSwapService_elev->>KernelInterop: GetPhysicalMemoryBytes().Available before
MemSwapService_elev->>MemSwapService_elev: AcquirePrivileges()
MemSwapService_elev->>MemSwapService_elev: MemorySwap(SwapScope.All)
MemSwapService_elev->>SwapWorks: Execute swap operations
SwapWorks-->>MemSwapService_elev: Completed
MemSwapService_elev->>KernelInterop: GetPhysicalMemoryBytes().Available after
MemSwapService_elev->>Context: RequestExit(diffInKB)
else ElevatedNoAdmin
MemSwapService_elev->>Context: Error("缺少管理员权限")
MemSwapService_elev->>Context: RequestExit(-1)
end
ElevatedPCL-->>PageToolsTest: Process exit code
PageToolsTest->>PageToolsTest: num = ExitCode * 1024
PageToolsTest->>User: Show result hint if num > 1024L
end
Sequence diagram for MemSwapService.MemorySwap and SwapWorkssequenceDiagram
participant Caller as MemSwapService
participant MemSwapService
participant ProcessInterop
participant SwapWorks
participant NtInterop
Caller->>MemSwapService: MemorySwap(scope)
MemSwapService->>MemSwapService: _memSwapLock.Wait(0)
alt LockBusy
MemSwapService-->>Caller: false
else LockAcquired
MemSwapService->>ProcessInterop: IsAdmin()
alt NotAdmin
MemSwapService-->>Caller: false
else IsAdmin
MemSwapService->>MemSwapService: Check flags in scope
opt EmptyWorkingSets
MemSwapService->>SwapWorks: EmptyWorkingSets()
SwapWorks->>NtInterop: SetSystemInformation(SystemMemoryListInformation, 2)
end
opt FlushFileCache
MemSwapService->>SwapWorks: FlushFileCache()
SwapWorks->>NtInterop: SetSystemInformation(SystemFileCacheInformationEx, SYSTEM_FILECACHE_INFORMATION)
end
opt FlushModifiedList
MemSwapService->>SwapWorks: FlushModifiedList()
SwapWorks->>NtInterop: SetSystemInformation(SystemMemoryListInformation, 3)
end
opt PurgeStandbyList
MemSwapService->>SwapWorks: PurgeStandbyList()
SwapWorks->>NtInterop: SetSystemInformation(SystemMemoryListInformation, 4)
end
opt PurgeLowPriorityStandbyList
MemSwapService->>SwapWorks: PurgeLowPriorityStandbyList()
SwapWorks->>NtInterop: SetSystemInformation(SystemMemoryListInformation, 5)
end
opt RegistryReconciliation
MemSwapService->>SwapWorks: RegistryReconciliation()
SwapWorks->>NtInterop: SetSystemInformation(SystemRegistryReconciliationInformation, 0)
end
opt CombinePhysicalMemory
MemSwapService->>SwapWorks: CombinePhysicalMemory()
SwapWorks->>NtInterop: SetSystemInformation(SystemCombinePhysicalMemoryInformation, MEMORY_COMBINE_INFORMATION_EX)
end
MemSwapService-->>Caller: true
end
MemSwapService->>MemSwapService: _memSwapLock.Release()
end
Updated class diagram for mem swap and IO utilitiesclassDiagram
class MemSwapService {
<<sealed>>
- static SemaphoreSlim _memSwapLock
+ static void AcquirePrivileges()
+ static bool MemorySwap(SwapScope scope)
- static void _CheckRequest()
}
class SwapWorks {
<<static>>
- static void _ExecuteMemoryListOperation(int infoValue)
- static void _ExecuteStructureOperation~T~(T structure, NtInterop.SystemInformationClass infoClass)
+ static void EmptyWorkingSets()
+ static void FlushFileCache()
+ static void FlushModifiedList()
+ static void PurgeStandbyList()
+ static void PurgeLowPriorityStandbyList()
+ static void RegistryReconciliation()
+ static void CombinePhysicalMemory()
}
class SwapScope {
<<enum>>
None
EmptyWorkingSets
FlushFileCache
FlushModifiedList
PurgeStandbyList
PurgeLowPriorityStandbyList
RegistryReconciliation
CombinePhysicalMemory
All
}
class ByteStream {
- Stream BaseStream
+ long Length
+ ByteStream(Stream stream)
+ int Read(byte[] buffer, int offset, int count)
+ void Write(byte[] buffer, int offset, int count)
+ long Seek(long offset, SeekOrigin origin)
+ void Flush()
+ long Position
+ void Close()
+ string GetReadableLength()
- static string[] _Units
+ static string GetReadableLength(long length, int startUnit)
}
class ModBase {
<<module>>
+ string GetString(long FileSize)
}
class ProcessInterop {
<<static>>
+ bool IsAdmin()
+ Process Start(string path, string arguments, bool runAsAdmin)
}
class NtInterop {
<<static>>
+ void SetPrivilege(SePrivilege privilege, bool enable, bool thread)
+ void SetSystemInformation(SystemInformationClass infoClass, IntPtr info, uint length)
}
class KernelInterop {
<<static>>
+ PhysicalMemoryInfo GetPhysicalMemoryBytes()
+ ulong GetAvailablePhysicalMemoryBytes()
}
class Context {
<<static>>
+ void Info(string message)
+ void Warn(string message)
+ void Error(string message)
+ void Error(string message, Exception ex)
+ void RequestExit(int code)
}
ModBase ..> ByteStream : uses
MemSwapService ..> SwapScope : uses
MemSwapService ..> SwapWorks : uses
MemSwapService ..> NtInterop : uses
MemSwapService ..> KernelInterop : uses
MemSwapService ..> ProcessInterop : uses
MemSwapService ..> ByteStream : uses
MemSwapService ..> Context : uses
SwapWorks ..> NtInterop : uses
ProcessInterop ..> SystemDiagnosticsProcess : wraps
class SystemDiagnosticsProcess {
<<framework>>
}
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并给出了一些高层次的反馈:
- 在
ByteStream.GetReadableLength中,当参数为long.MinValue时,取负号-length会发生溢出;建议在取绝对值前先转换为decimal,或者使用安全的辅助方法来处理这个边界情况。 - 在
MemSwapService._CheckRequest中,当MemorySwap返回false时,该方法只记录日志并返回,但不会退出,这改变了之前 CLI 对内存请求总是终止的行为;建议在这种情况下返回一个非零退出码,以便让调用方的行为契约保持可预测。 MemSwapService中的_memSwapLock字段在初始化之后就不再发生变化;将其标记为readonly能更好地表达意图并避免意外的重新赋值。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In ByteStream.GetReadableLength, the negation `-length` will overflow for `long.MinValue`; consider casting to decimal before taking the absolute value or using a safe helper to handle that edge case.
- In MemSwapService._CheckRequest, when MemorySwap returns false the method just logs and returns without exiting, which changes the previous CLI behavior of always terminating for memory requests; consider returning a non-zero exit code there to keep the contract predictable for callers.
- The `_memSwapLock` field in MemSwapService never changes after initialization; marking it as `readonly` would better express intent and avoid accidental reassignment.
## Individual Comments
### Comment 1
<location path="PCL.Core/IO/ByteStream.cs" line_range="12-21" />
<code_context>
+ private static readonly string[] _Units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
</code_context>
<issue_to_address>
**issue (bug_risk):** Negative or out-of-range `startUnit` values can cause index errors when accessing `_Units`.
In `GetReadableLength(long length, int startUnit = 0)`, `startUnit` is used directly as `unitIndex` and then applied as `_Units[unitIndex]`. If `startUnit` is negative or >= `_Units.Length`, this will throw `IndexOutOfRangeException` before your intended `ArgumentOutOfRangeException`. Add a guard (e.g., `0 <= startUnit && startUnit < _Units.Length`) before indexing to ensure consistent, explicit error handling.
</issue_to_address>帮我变得更有用!请对每条评论点 👍 或 👎,我会根据反馈改进后续的评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- In ByteStream.GetReadableLength, the negation
-lengthwill overflow forlong.MinValue; consider casting to decimal before taking the absolute value or using a safe helper to handle that edge case. - In MemSwapService._CheckRequest, when MemorySwap returns false the method just logs and returns without exiting, which changes the previous CLI behavior of always terminating for memory requests; consider returning a non-zero exit code there to keep the contract predictable for callers.
- The
_memSwapLockfield in MemSwapService never changes after initialization; marking it asreadonlywould better express intent and avoid accidental reassignment.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In ByteStream.GetReadableLength, the negation `-length` will overflow for `long.MinValue`; consider casting to decimal before taking the absolute value or using a safe helper to handle that edge case.
- In MemSwapService._CheckRequest, when MemorySwap returns false the method just logs and returns without exiting, which changes the previous CLI behavior of always terminating for memory requests; consider returning a non-zero exit code there to keep the contract predictable for callers.
- The `_memSwapLock` field in MemSwapService never changes after initialization; marking it as `readonly` would better express intent and avoid accidental reassignment.
## Individual Comments
### Comment 1
<location path="PCL.Core/IO/ByteStream.cs" line_range="12-21" />
<code_context>
+ private static readonly string[] _Units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
</code_context>
<issue_to_address>
**issue (bug_risk):** Negative or out-of-range `startUnit` values can cause index errors when accessing `_Units`.
In `GetReadableLength(long length, int startUnit = 0)`, `startUnit` is used directly as `unitIndex` and then applied as `_Units[unitIndex]`. If `startUnit` is negative or >= `_Units.Length`, this will throw `IndexOutOfRangeException` before your intended `ArgumentOutOfRangeException`. Add a guard (e.g., `0 <= startUnit && startUnit < _Units.Length`) before indexing to ensure consistent, explicit error handling.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
程序想要写日志,但是没有初始化,没有 Context @ruattd |
由 Sourcery 生成的摘要
重构并将内存优化功能集中到专用的 MemSwap 服务中,该服务可在具有或不具有管理员权限的情况下调用,同时改进大小格式化工具并提升进程启动的可靠性。
新功能:
错误修复:
改进:
Original summary in English
Summary by Sourcery
Refactor and centralize the memory optimization feature into a dedicated MemSwap service that can be invoked with or without admin privileges while improving size formatting utilities and process startup reliability.
New Features:
Bug Fixes:
Enhancements: