├── .editorconfig ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── event-ci.yml │ ├── event-release.yml │ ├── reuse-build-test.yml │ └── reuse-gitversion.yml ├── .gitignore ├── Directory.Build.props ├── LICENSE ├── README.md ├── RadeonSoftwareSlimmer.sln ├── build ├── build.ps1 ├── publish.ps1 ├── release-notes-template.md └── test.ps1 ├── local-ci.ps1 ├── nuget.config ├── src ├── RadeonSoftwareSlimmer │ ├── App.xaml │ ├── App.xaml.cs │ ├── AssemblyInfo.cs │ ├── Intefaces │ │ ├── IRegistry.cs │ │ └── IRegistryKey.cs │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Models │ │ ├── LoggingModel.cs │ │ ├── PostInstall │ │ │ ├── HostServiceModel.cs │ │ │ ├── InstalledListModel.cs │ │ │ ├── InstalledModel.cs │ │ │ ├── RunningHostServiceModel.cs │ │ │ ├── RunningProcessModel.cs │ │ │ ├── ScheduledTaskListModel.cs │ │ │ ├── ScheduledTaskModel.cs │ │ │ ├── ServiceListModel.cs │ │ │ ├── ServiceModel.cs │ │ │ ├── TempFileListModel.cs │ │ │ ├── TempFileModel.cs │ │ │ └── WindowsAppStartupModel.cs │ │ └── PreInstall │ │ │ ├── DisplayComponentListModel.cs │ │ │ ├── DisplayComponentModel.cs │ │ │ ├── InstallerFilesModel.cs │ │ │ ├── PackageListModel.cs │ │ │ ├── PackageModel.cs │ │ │ ├── ScheduledTaskXmlListModel.cs │ │ │ └── ScheduledTaskXmlModel.cs │ ├── RadeonSoftwareSlimmer.csproj │ ├── Services │ │ ├── ProcessHandler.cs │ │ ├── ThemeService.cs │ │ ├── WindowsRegistry.cs │ │ └── WindowsRegistryKey.cs │ ├── ViewModels │ │ ├── PostInstallViewModel.cs │ │ ├── PreInstallViewModel.cs │ │ └── StaticViewModel.cs │ ├── Views │ │ ├── AboutView.xaml │ │ ├── AboutView.xaml.cs │ │ ├── HelpLink.xaml │ │ ├── HelpLink.xaml.cs │ │ ├── LoggingView.xaml │ │ ├── LoggingView.xaml.cs │ │ ├── MessageView.xaml │ │ ├── MessageView.xaml.cs │ │ ├── PostInstallView.xaml │ │ ├── PostInstallView.xaml.cs │ │ ├── PreInstallView.xaml │ │ └── PreInstallView.xaml.cs │ ├── app.manifest │ └── icon.ico └── Shared │ ├── 7-Zip │ ├── 7z.dll │ ├── 7z.exe │ └── License.txt │ ├── Shared.projitems │ └── Shared.shproj └── test └── RadeonSoftwareSlimmer.Test ├── Models ├── PostInstall │ ├── HostServicesModelTests.cs │ ├── InstalledModelTests.cs │ ├── TempFileListModelTest.cs │ ├── TempFileModelTest.cs │ └── WindowsAppStartupModelTest.cs └── PreInstall │ ├── DisplayComponentListModelTest.cs │ ├── DisplayComponentModelTest.cs │ ├── InstallerFilesModleTest.cs │ ├── PackageListModelTest.cs │ ├── PackageModelTest.cs │ ├── ScheduledTaskXmlListModel.cs │ └── ScheduledTaskXmlModelTest.cs ├── RadeonSoftwareSlimmer.Test.csproj ├── RadeonSoftwareSlimmer.Test.runsettings ├── Services └── ProcessHandlerTests.cs ├── TestData ├── PackageModel_cccmanifest.json ├── PackageModel_installmanifest.json ├── ScheduledTaskXmlListModel_Task10.xml ├── ScheduledTaskXmlListModel_Task7.xml ├── ScheduledTaskXmlListModel_TaskDisabled.xml ├── ScheduledTaskXmlListModel_TaskEnabled.xml └── ScheduledTaskXmlListModel_TaskVista.xml └── TestDoubles ├── FakeRegistry.cs ├── FakeRegistryKey.cs └── RegistryValue.cs /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # CA1816: Dispose methods should call SuppressFinalize 4 | dotnet_diagnostic.CA1816.severity = none 5 | 6 | # CA1303: Do not pass literals as localized parameters 7 | dotnet_diagnostic.CA1303.severity = none 8 | 9 | # IDE0017: Simplify object initialization 10 | dotnet_style_object_initializer = false:suggestion 11 | 12 | # CA2007: Consider calling ConfigureAwait on the awaited task 13 | dotnet_diagnostic.CA2007.severity = none 14 | 15 | # IDE1006: Naming Styles 16 | dotnet_diagnostic.IDE1006.severity = none 17 | 18 | # CA1707: Identifiers should not contain underscores 19 | dotnet_diagnostic.CA1707.severity = none 20 | 21 | # CA1031: Do not catch general exception types 22 | dotnet_diagnostic.CA1031.severity = none 23 | 24 | # IDE0001: Simplify Names 25 | dotnet_diagnostic.IDE0001.severity = none 26 | 27 | # CA1416: Validate platform compatibility 28 | dotnet_diagnostic.CA1416.severity = none 29 | 30 | # S1066: Collapsible "if" statements should be merged 31 | dotnet_diagnostic.S1066.severity = none 32 | 33 | # IDE0016: Use 'throw' expression 34 | dotnet_diagnostic.IDE0016.severity = none 35 | 36 | # IDE0031: Use null propagation 37 | dotnet_diagnostic.IDE0031.severity = none 38 | 39 | # CA1510: Use ArgumentNullException throw helper 40 | # Not available in .NET 4.8 41 | dotnet_diagnostic.CA1510.severity = none 42 | 43 | # ******************************************************************************************* 44 | # SonarAnalyzer Rules 45 | # S3897: Classes that provide "Equals()" should implement "IEquatable" 46 | dotnet_diagnostic.S3897.severity = silent 47 | 48 | # S4035: Classes implementing "IEquatable" should be sealed 49 | dotnet_diagnostic.S4035.severity = silent 50 | 51 | # S3458: Empty "case" clauses that fall through to the "default" should be omitted 52 | dotnet_diagnostic.S3458.severity = none 53 | 54 | # S1939: Inheritance list should not be redundant 55 | dotnet_diagnostic.S1939.severity = none 56 | 57 | # S1172: Unused method parameters should be removed 58 | # Rule is not working properly 59 | dotnet_diagnostic.S1172.severity = none 60 | # ******************************************************************************************** 61 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # https://www.git-scm.com/docs/gitattributes 2 | # https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings 3 | 4 | # Set the default behavior, in case people don't have core.autocrlf set. 5 | * text=auto 6 | 7 | # Declare files that will always have CRLF line endings on checkout. 8 | *.md text eol=crlf 9 | 10 | # Denote all files that are truly binary and should not be modified. 11 | *.{dll,exe,ico} binary -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | groups: 13 | actions-updates: 14 | applies-to: version-updates 15 | patterns: 16 | - "*" 17 | 18 | - package-ecosystem: "nuget" 19 | directory: "/" 20 | schedule: 21 | interval: "weekly" 22 | groups: 23 | nuget-updates: 24 | applies-to: version-updates 25 | patterns: 26 | - "*" 27 | -------------------------------------------------------------------------------- /.github/workflows/event-ci.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - '**' 8 | paths-ignore: 9 | - 'README.md' 10 | pull_request: 11 | branches: 12 | - master 13 | types: [opened, reopened, synchronize] 14 | 15 | jobs: 16 | gitVersion: 17 | name: Get Version 18 | uses: ./.github/workflows/reuse-gitversion.yml 19 | 20 | buildTest: 21 | name: Build and Test 22 | needs: gitVersion 23 | uses: ./.github/workflows/reuse-build-test.yml 24 | with: 25 | build-version: ${{ needs.gitVersion.outputs.version }} 26 | -------------------------------------------------------------------------------- /.github/workflows/event-release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | tags: 7 | - '[1-9].[0-9]+.[0-9]+' 8 | # git tag 1.2.3 9 | # git push --tags 10 | 11 | jobs: 12 | gitVersion: 13 | name: Get Version 14 | uses: ./.github/workflows/reuse-gitversion.yml 15 | 16 | buildTest: 17 | name: Build, Test and Publish 18 | needs: gitVersion 19 | uses: ./.github/workflows/reuse-build-test.yml 20 | with: 21 | build-version: ${{ needs.gitVersion.outputs.version }} 22 | 23 | release: 24 | name: Create Release 25 | needs: [gitVersion, buildTest] 26 | runs-on: ubuntu-latest 27 | 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v4 31 | with: 32 | fetch-depth: 0 33 | 34 | - name: Download Published Artifact 35 | uses: actions/download-artifact@v4 36 | with: 37 | name: published-artifact 38 | 39 | - name: List Artifacts 40 | run: ls -R 41 | 42 | # https://github.com/marketplace/actions/create-release 43 | - name: Create Release 44 | uses: ncipollo/release-action@v1 45 | with: 46 | artifactErrorsFailBuild: true 47 | artifacts: ./RadeonSoftwareSlimmer_*_net*.zip 48 | artifactContentType: application/zip 49 | bodyFile: ./build/release-notes-template.md 50 | draft: true 51 | generateReleaseNotes: false 52 | name: Radeon Software Slimmer ${{ needs.gitVersion.outputs.version }} 53 | prerelease: false 54 | token: ${{ secrets.GITHUB_TOKEN }} 55 | -------------------------------------------------------------------------------- /.github/workflows/reuse-build-test.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | build-version: 7 | description: 'The version to build' 8 | default: 1.0.0 9 | required: true 10 | type: string 11 | 12 | jobs: 13 | buildTestPublish: 14 | name: Build Test Publish 15 | runs-on: windows-latest 16 | env: 17 | BUILD_VERSION: ${{ inputs.build-version }} 18 | DOTNET_CLI_TELEMETRY_OPTOUT: true 19 | DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE: true 20 | DOTNET_NOLOGO: true 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | 28 | - name: Build 29 | run: ./build/build.ps1 30 | 31 | - name: Test 32 | run: ./build/test.ps1 33 | 34 | # https://github.com/marketplace/actions/upload-a-build-artifact 35 | - name: Upload Test Results 36 | uses: actions/upload-artifact@v4 37 | with: 38 | name: test-results 39 | path: ./artifacts/tests/*.trx 40 | if-no-files-found: warn 41 | 42 | # https://github.com/marketplace/actions/test-reporter 43 | - name: Publish Test Results 44 | if: success() || failure() 45 | uses: dorny/test-reporter@v2 46 | with: 47 | artifact: test-results 48 | name: Test Results 49 | path: '*.trx' 50 | reporter: dotnet-trx 51 | only-summary: false 52 | fail-on-error: true 53 | fail-on-empty: true 54 | 55 | - name: Publish 56 | run: ./build/publish.ps1 57 | 58 | - name: Upload Published Artifact 59 | uses: actions/upload-artifact@v4 60 | with: 61 | name: published-artifact 62 | path: ./artifacts/publish/RadeonSoftwareSlimmer_*_net*.zip 63 | if-no-files-found: error 64 | compression-level: 0 65 | -------------------------------------------------------------------------------- /.github/workflows/reuse-gitversion.yml: -------------------------------------------------------------------------------- 1 | name: GitVersion 2 | 3 | on: 4 | workflow_call: 5 | # https://docs.github.com/en/actions/sharing-automations/reusing-workflows#using-outputs-from-a-reusable-workflow 6 | outputs: 7 | version: 8 | description: 'The full SemVer from GitVersion' 9 | value: ${{ jobs.GitVersion.outputs.FullSemVer }} 10 | 11 | jobs: 12 | GitVersion: 13 | # https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#choosing-github-hosted-runners 14 | # https://github.com/actions/runner-images 15 | runs-on: ubuntu-latest 16 | 17 | outputs: 18 | FullSemVer: ${{ steps.version_step.outputs.fullSemVer }} 19 | 20 | steps: 21 | # https://github.com/marketplace/actions/checkout 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | with: 25 | fetch-depth: 0 26 | 27 | # https://github.com/marketplace/actions/gittools 28 | - name: Install GitVersion 29 | uses: gittools/actions/gitversion/setup@v3 30 | with: 31 | versionSpec: '6.0.x' 32 | preferLatestVersion: true 33 | 34 | - name: Determine Version 35 | id: version_step 36 | uses: gittools/actions/gitversion/execute@v3 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | # but not Directory.Build.rsp, as it configures directory-level build defaults 86 | !Directory.Build.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.tmp_proj 93 | *_wpftmp.csproj 94 | *.log 95 | *.tlog 96 | *.vspscc 97 | *.vssscc 98 | .builds 99 | *.pidb 100 | *.svclog 101 | *.scc 102 | 103 | # Chutzpah Test files 104 | _Chutzpah* 105 | 106 | # Visual C++ cache files 107 | ipch/ 108 | *.aps 109 | *.ncb 110 | *.opendb 111 | *.opensdf 112 | *.sdf 113 | *.cachefile 114 | *.VC.db 115 | *.VC.VC.opendb 116 | 117 | # Visual Studio profiler 118 | *.psess 119 | *.vsp 120 | *.vspx 121 | *.sap 122 | 123 | # Visual Studio Trace Files 124 | *.e2e 125 | 126 | # TFS 2012 Local Workspace 127 | $tf/ 128 | 129 | # Guidance Automation Toolkit 130 | *.gpState 131 | 132 | # ReSharper is a .NET coding add-in 133 | _ReSharper*/ 134 | *.[Rr]e[Ss]harper 135 | *.DotSettings.user 136 | 137 | # TeamCity is a build add-in 138 | _TeamCity* 139 | 140 | # DotCover is a Code Coverage Tool 141 | *.dotCover 142 | 143 | # AxoCover is a Code Coverage Tool 144 | .axoCover/* 145 | !.axoCover/settings.json 146 | 147 | # Coverlet is a free, cross platform Code Coverage Tool 148 | coverage*.json 149 | coverage*.xml 150 | coverage*.info 151 | 152 | # Visual Studio code coverage results 153 | *.coverage 154 | *.coveragexml 155 | 156 | # NCrunch 157 | _NCrunch_* 158 | .*crunch*.local.xml 159 | nCrunchTemp_* 160 | 161 | # MightyMoose 162 | *.mm.* 163 | AutoTest.Net/ 164 | 165 | # Web workbench (sass) 166 | .sass-cache/ 167 | 168 | # Installshield output folder 169 | [Ee]xpress/ 170 | 171 | # DocProject is a documentation generator add-in 172 | DocProject/buildhelp/ 173 | DocProject/Help/*.HxT 174 | DocProject/Help/*.HxC 175 | DocProject/Help/*.hhc 176 | DocProject/Help/*.hhk 177 | DocProject/Help/*.hhp 178 | DocProject/Help/Html2 179 | DocProject/Help/html 180 | 181 | # Click-Once directory 182 | publish/ 183 | 184 | # Publish Web Output 185 | *.[Pp]ublish.xml 186 | *.azurePubxml 187 | # Note: Comment the next line if you want to checkin your web deploy settings, 188 | # but database connection strings (with potential passwords) will be unencrypted 189 | *.pubxml 190 | *.publishproj 191 | 192 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 193 | # checkin your Azure Web App publish settings, but sensitive information contained 194 | # in these scripts will be unencrypted 195 | PublishScripts/ 196 | 197 | # NuGet Packages 198 | *.nupkg 199 | # NuGet Symbol Packages 200 | *.snupkg 201 | # The packages folder can be ignored because of Package Restore 202 | **/[Pp]ackages/* 203 | # except build/, which is used as an MSBuild target. 204 | !**/[Pp]ackages/build/ 205 | # Uncomment if necessary however generally it will be regenerated when needed 206 | #!**/[Pp]ackages/repositories.config 207 | # NuGet v3's project.json files produces more ignorable files 208 | *.nuget.props 209 | *.nuget.targets 210 | 211 | # Microsoft Azure Build Output 212 | csx/ 213 | *.build.csdef 214 | 215 | # Microsoft Azure Emulator 216 | ecf/ 217 | rcf/ 218 | 219 | # Windows Store app package directories and files 220 | AppPackages/ 221 | BundleArtifacts/ 222 | Package.StoreAssociation.xml 223 | _pkginfo.txt 224 | *.appx 225 | *.appxbundle 226 | *.appxupload 227 | 228 | # Visual Studio cache files 229 | # files ending in .cache can be ignored 230 | *.[Cc]ache 231 | # but keep track of directories ending in .cache 232 | !?*.[Cc]ache/ 233 | 234 | # Others 235 | ClientBin/ 236 | ~$* 237 | *~ 238 | *.dbmdl 239 | *.dbproj.schemaview 240 | *.jfm 241 | *.pfx 242 | *.publishsettings 243 | orleans.codegen.cs 244 | 245 | # Including strong name files can present a security risk 246 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 247 | #*.snk 248 | 249 | # Since there are multiple workflows, uncomment next line to ignore bower_components 250 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 251 | #bower_components/ 252 | 253 | # RIA/Silverlight projects 254 | Generated_Code/ 255 | 256 | # Backup & report files from converting an old project file 257 | # to a newer Visual Studio version. Backup files are not needed, 258 | # because we have git ;-) 259 | _UpgradeReport_Files/ 260 | Backup*/ 261 | UpgradeLog*.XML 262 | UpgradeLog*.htm 263 | ServiceFabricBackup/ 264 | *.rptproj.bak 265 | 266 | # SQL Server files 267 | *.mdf 268 | *.ldf 269 | *.ndf 270 | 271 | # Business Intelligence projects 272 | *.rdl.data 273 | *.bim.layout 274 | *.bim_*.settings 275 | *.rptproj.rsuser 276 | *- [Bb]ackup.rdl 277 | *- [Bb]ackup ([0-9]).rdl 278 | *- [Bb]ackup ([0-9][0-9]).rdl 279 | 280 | # Microsoft Fakes 281 | FakesAssemblies/ 282 | 283 | # GhostDoc plugin setting file 284 | *.GhostDoc.xml 285 | 286 | # Node.js Tools for Visual Studio 287 | .ntvs_analysis.dat 288 | node_modules/ 289 | 290 | # Visual Studio 6 build log 291 | *.plg 292 | 293 | # Visual Studio 6 workspace options file 294 | *.opt 295 | 296 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 297 | *.vbw 298 | 299 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 300 | *.vbp 301 | 302 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 303 | *.dsw 304 | *.dsp 305 | 306 | # Visual Studio 6 technical files 307 | *.ncb 308 | *.aps 309 | 310 | # Visual Studio LightSwitch build output 311 | **/*.HTMLClient/GeneratedArtifacts 312 | **/*.DesktopClient/GeneratedArtifacts 313 | **/*.DesktopClient/ModelManifest.xml 314 | **/*.Server/GeneratedArtifacts 315 | **/*.Server/ModelManifest.xml 316 | _Pvt_Extensions 317 | 318 | # Paket dependency manager 319 | .paket/paket.exe 320 | paket-files/ 321 | 322 | # FAKE - F# Make 323 | .fake/ 324 | 325 | # CodeRush personal settings 326 | .cr/personal 327 | 328 | # Python Tools for Visual Studio (PTVS) 329 | __pycache__/ 330 | *.pyc 331 | 332 | # Cake - Uncomment if you are using it 333 | # tools/** 334 | # !tools/packages.config 335 | 336 | # Tabs Studio 337 | *.tss 338 | 339 | # Telerik's JustMock configuration file 340 | *.jmconfig 341 | 342 | # BizTalk build output 343 | *.btp.cs 344 | *.btm.cs 345 | *.odx.cs 346 | *.xsd.cs 347 | 348 | # OpenCover UI analysis results 349 | OpenCover/ 350 | 351 | # Azure Stream Analytics local run output 352 | ASALocalRun/ 353 | 354 | # MSBuild Binary and Structured Log 355 | *.binlog 356 | 357 | # NVidia Nsight GPU debugger configuration file 358 | *.nvuser 359 | 360 | # MFractors (Xamarin productivity tool) working folder 361 | .mfractor/ 362 | 363 | # Local History for Visual Studio 364 | .localhistory/ 365 | 366 | # Visual Studio History (VSHistory) files 367 | .vshistory/ 368 | 369 | # BeatPulse healthcheck temp database 370 | healthchecksdb 371 | 372 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 373 | MigrationBackup/ 374 | 375 | # Ionide (cross platform F# VS Code tools) working folder 376 | .ionide/ 377 | 378 | # Fody - auto-generated XML schema 379 | FodyWeavers.xsd 380 | 381 | # VS Code files for those working on multiple tools 382 | .vscode/* 383 | !.vscode/settings.json 384 | !.vscode/tasks.json 385 | !.vscode/launch.json 386 | !.vscode/extensions.json 387 | *.code-workspace 388 | 389 | # Local History for Visual Studio Code 390 | .history/ 391 | 392 | # Windows Installer files from build outputs 393 | *.cab 394 | *.msi 395 | *.msix 396 | *.msm 397 | *.msp 398 | 399 | # JetBrains Rider 400 | *.sln.iml 401 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0-windows;net8.0-windows;net48 4 | win-x64 5 | x64 6 | 7 | 8 | 7.3 9 | 10 | True 11 | True 12 | True 13 | latest 14 | True 15 | 16 | true 17 | false 18 | true 19 | false 20 | false 21 | false 22 | false 23 | en-US 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | true 33 | 34 | 35 | true 36 | true 37 | 38 | 39 | 40 | 41 | false 42 | false 43 | false 44 | 45 | 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Radeon Software Slimmer 2 | 3 | **https://github.com/GSDragoon/RadeonSoftwareSlimmer** 4 | 5 | ![Release](https://github.com/GSDragoon/RadeonSoftwareSlimmer/workflows/Release/badge.svg) 6 | ![Continuous-Integration](https://github.com/GSDragoon/RadeonSoftwareSlimmer/workflows/Continuous-Integration/badge.svg) 7 | 8 | ![Latest-Release-Version](https://img.shields.io/github/v/release/GSDragoon/RadeonSoftwareSlimmer?color=yellow) 9 | ![Latest-Release-Date](https://img.shields.io/github/release-date/GSDragoon/RadeonSoftwareSlimmer) 10 | ![Total-Downloads](https://img.shields.io/github/downloads/GSDragoon/RadeonSoftwareSlimmer/total?color=blue) 11 | ![Latest-Downloads](https://img.shields.io/github/downloads/GSDragoon/RadeonSoftwareSlimmer/latest/total?color=blue) 12 | 13 | *** 14 | 15 | Radeon Software Slimmer is a utility to trim down the "[bloat](https://en.wikipedia.org/wiki/Software_bloat)" with the [Radeon Software](https://www.amd.com/en/technologies/radeon-software) for AMD GPUs on Microsoft Windows. 16 | 17 | Radeon Software Adrenalin 2020 Edition introduced a ton of new features. You can read about it [here](https://community.amd.com/community/gaming/blog/2019/12/10/change-the-way-you-game-with-amd-radeon-software-adrenalin-2020-edition). While many enjoy these features, there are some that do not. And to those users, they feel the software contains a lot of unnecessary bloat without any way to not install or disable it. Radeon Software Slimmer is aimed at those users who want to keep their systems as slim as possible. This software is not meant to disrespect AMD or it's hard-working employees. It was inspired by the [NVIDIA driver slimming utility](https://www.guru3d.com/files-details/nvidia-driver-slimming-utility.html). 18 | 19 | Radeon Software Slimmer is completely free and open source. It does not contain any advertisements, telemetry or reach out to the internet. Logging is captured within the application, for troubleshooting purposes, but does not write to file or leave the application unless you explicitly do so. 20 | 21 | ## Disclaimer 22 | 23 | This software is **NOT** owned, supported or endorsed by [Advanced Micro Devices, Inc. (AMD)](https://www.amd.com/). 24 | 25 | Improper use could cause system instability. **Use at your own risk!** 26 | 27 | ## Getting Started 28 | 29 | Documentation can be found on the [Wiki](https://github.com/GSDragoon/RadeonSoftwareSlimmer/wiki). 30 | 31 | Requirements: 32 | * Administrator rights 33 | * Windows 10 64-bit or Windows 11 (Latest version recommended) 34 | * .NET (Either ***one*** of the following) 35 | * [.NET Framework 4.8 Runtime](https://dotnet.microsoft.com/download/dotnet-framework/net48) (Included with Windows 10 1903 [May 2019 update] and later) 36 | * [.NET Framework 4.8.1 Runtime](https://dotnet.microsoft.com/download/dotnet-framework/net481) (Included with Windows 11 22H2 and later) 37 | * [.NET Desktop Runtime 8.0 x64](https://dotnet.microsoft.com/download/dotnet/8.0) (latest release recommended) 38 | * [.NET Desktop Runtime 9.0 x64](https://dotnet.microsoft.com/download/dotnet/9.0) (latest release recommended) 39 | 40 | Installation: 41 | 1. Download the version you want on the [Releases page](https://github.com/GSDragoon/RadeonSoftwareSlimmer/releases). 42 | 2. Extract the contents of the downloaded zip file to a folder of your choice. If upgrading from a previous version, it is highly recommended to deleted the old files first. There are no persistent configuration files or anything like that. 43 | 3. Run `RadeonSoftwareSlimmer.exe` 44 | 45 | ## Third Party Usage 46 | 47 | Thanks to the following third parties used with this software: 48 | 49 | * .NET 50 | * https://dotnet.microsoft.com/ 51 | * Built with .NET and related Microsoft libraries 52 | * 7-Zip 53 | * https://www.7-zip.org/ 54 | * 7z.exe included in download 55 | * Used for decompressing the Radeon Software installer files 56 | * Radeon profile icon 57 | * http://www.iconarchive.com/show/papirus-apps-icons-by-papirus-team/radeon-profile-icon.html 58 | * Main application icon 59 | * MahApps 60 | * https://mahapps.com/ 61 | * UI controls, styles, themes and more 62 | * Json.NET 63 | * https://www.newtonsoft.com/json 64 | * Used for reading json files with the Radeon Software installer 65 | * Task Scheduler Manged Wrapper 66 | * https://github.com/dahall/taskscheduler 67 | * Used to read and modify system scheduled tasks 68 | * System.IO.Abstractions 69 | * https://github.com/System-IO-Abstractions/System.IO.Abstractions 70 | * Provides abstractions for System.IO for testability 71 | * Shields.io 72 | * https://shields.io/ 73 | * Provides badges on readme 74 | -------------------------------------------------------------------------------- /RadeonSoftwareSlimmer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33205.214 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RadeonSoftwareSlimmer", "src\RadeonSoftwareSlimmer\RadeonSoftwareSlimmer.csproj", "{A57F631F-11BB-4D48-A795-B90039733F4C}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7785ED3B-B4D4-41C1-AEBF-002B25AB3E38}" 9 | ProjectSection(SolutionItems) = preProject 10 | .editorconfig = .editorconfig 11 | .gitattributes = .gitattributes 12 | .gitignore = .gitignore 13 | local-ci.ps1 = local-ci.ps1 14 | nuget.config = nuget.config 15 | README.md = README.md 16 | EndProjectSection 17 | EndProject 18 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Shared", "src\Shared\Shared.shproj", "{9B80E4B0-8113-4FD6-A3B2-F67E98604F6C}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RadeonSoftwareSlimmer.Test", "test\RadeonSoftwareSlimmer.Test\RadeonSoftwareSlimmer.Test.csproj", "{16BE9BC0-E55D-47B2-9B57-4F7D5D18220B}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|x64 = Debug|x64 25 | Release|x64 = Release|x64 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {A57F631F-11BB-4D48-A795-B90039733F4C}.Debug|x64.ActiveCfg = Debug|x64 29 | {A57F631F-11BB-4D48-A795-B90039733F4C}.Debug|x64.Build.0 = Debug|x64 30 | {A57F631F-11BB-4D48-A795-B90039733F4C}.Release|x64.ActiveCfg = Release|x64 31 | {A57F631F-11BB-4D48-A795-B90039733F4C}.Release|x64.Build.0 = Release|x64 32 | {16BE9BC0-E55D-47B2-9B57-4F7D5D18220B}.Debug|x64.ActiveCfg = Debug|x64 33 | {16BE9BC0-E55D-47B2-9B57-4F7D5D18220B}.Debug|x64.Build.0 = Debug|x64 34 | {16BE9BC0-E55D-47B2-9B57-4F7D5D18220B}.Release|x64.ActiveCfg = Release|x64 35 | {16BE9BC0-E55D-47B2-9B57-4F7D5D18220B}.Release|x64.Build.0 = Release|x64 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {BACD17E6-3BDC-4AA0-AC9E-54786CEB483D} 42 | EndGlobalSection 43 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 44 | src\Shared\Shared.projitems*{a57f631f-11bb-4d48-a795-b90039733f4c}*SharedItemsImports = 5 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /build/build.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = 'Stop' 2 | $ProgressPreference = 'SilentlyContinue' 3 | 4 | 5 | $version = $Env:BUILD_VERSION 6 | Write-Output "Version: ${version}" 7 | 8 | Write-Output '***** Building solution...' 9 | dotnet build --no-incremental --force --configuration Release -p:Version=$version --framework net9.0-windows 10 | dotnet build --no-incremental --force --configuration Release -p:Version=$version --framework net8.0-windows 11 | dotnet build --no-incremental --force --configuration Release -p:Version=$version --framework net48 12 | Write-Output '***** Done Building solution...' 13 | -------------------------------------------------------------------------------- /build/publish.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = 'Stop' 2 | $ProgressPreference = 'SilentlyContinue' 3 | 4 | 5 | $version = $Env:BUILD_VERSION 6 | Write-Output "Version: ${version}" 7 | 8 | 9 | Write-Output '***** Publishing Application...' 10 | dotnet publish .\src\RadeonSoftwareSlimmer\RadeonSoftwareSlimmer.csproj --force --configuration Release -p:Version=$version --framework net9.0-windows 11 | dotnet publish .\src\RadeonSoftwareSlimmer\RadeonSoftwareSlimmer.csproj --force --configuration Release -p:Version=$version --framework net8.0-windows 12 | dotnet publish .\src\RadeonSoftwareSlimmer\RadeonSoftwareSlimmer.csproj --force --configuration Release -p:Version=$version --framework net48 13 | Write-Output '***** Done Publishing Application...' 14 | 15 | 16 | Write-Output '***** Archiving Application...' 17 | $publishSrcDir = '.\artifacts\publish\RadeonSoftwareSlimmer' 18 | $publishDestDir = '.\artifacts\publish' 19 | 20 | Compress-Archive -Path "${publishSrcDir}\release_net9.0-windows_win-x64\*" -DestinationPath "${publishDestDir}\RadeonSoftwareSlimmer_${version}_net90.zip" 21 | Compress-Archive -Path "${publishSrcDir}\release_net8.0-windows_win-x64\*" -DestinationPath "${publishDestDir}\RadeonSoftwareSlimmer_${version}_net80.zip" 22 | Compress-Archive -Path "${publishSrcDir}\release_net48_win-x64\*" -DestinationPath "${publishDestDir}\RadeonSoftwareSlimmer_${version}_net48.zip" 23 | Write-Output '***** Done Archiving Application...' 24 | 25 | 26 | Write-Output '***** Archive Hashes (SHA256):' 27 | Get-Item -Path "${publishDestDir}\RadeonSoftwareSlimmer_*_net*.zip" | ForEach-Object { 28 | $hash = Get-FileHash -Path $_ 29 | Write-Output "$($_.Name): $($hash.hash)" 30 | } 31 | -------------------------------------------------------------------------------- /build/release-notes-template.md: -------------------------------------------------------------------------------- 1 | **New Features** 2 | * abc 3 | * 123 4 | 5 | **Changes to Existing Functionality** 6 | * abc 7 | * 123 8 | 9 | **Defects Fixed** 10 | * abc 11 | * 123 12 | 13 | **Dependencies Updated** 14 | * abc 15 | * 123 16 | 17 | **Other Changes** 18 | * abc 19 | * 123 -------------------------------------------------------------------------------- /build/test.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = 'Stop' 2 | $ProgressPreference = 'SilentlyContinue' 3 | 4 | 5 | $artifactPath = '.\artifacts' 6 | $resultsPath = '.\artifacts\tests' 7 | 8 | 9 | Write-Output '***** Installing Report Generator...' 10 | dotnet tool install dotnet-reportgenerator-globaltool --tool-path $artifactPath 11 | 12 | 13 | Write-Output '***** Testing solution...' 14 | # https://github.com/dotnet/sdk/issues/44991 - does not support artifact output 15 | $project = '.\test\RadeonSoftwareSlimmer.Test\RadeonSoftwareSlimmer.Test.csproj' 16 | 17 | dotnet test $project --no-build --configuration Release --results-directory $resultsPath --framework net9.0-windows 18 | dotnet test $project --no-build --configuration Release --results-directory $resultsPath --framework net8.0-windows 19 | dotnet test $project --no-build --configuration Release --results-directory $resultsPath --framework net48 20 | Write-Output '***** Done Testing solution...' 21 | 22 | 23 | Write-Output '***** Running Report Generator...' 24 | $reportGenArgs = @( 25 | "-reports:${resultsPath}\*\coverage.cobertura*.xml", 26 | "-targetdir:${artifactPath}\CoverageReports", 27 | '-reporttypes:Badges;Cobertura;Html;HtmlSummary;TextSummary', 28 | '--settings:createSubdirectoryForAllReportTypes=true' 29 | ) 30 | Start-Process -FilePath "${artifactPath}\reportgenerator.exe" -ArgumentList $reportGenArgs -NoNewWindow -Wait 31 | Get-Content -Path "${artifactPath}\CoverageReports\TextSummary\Summary.txt" 32 | -------------------------------------------------------------------------------- /local-ci.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | $ErrorActionPreference = 'Stop' 4 | $ProgressPreference = 'SilentlyContinue' 5 | 6 | 7 | $Env:BUILD_VERSION = '1.2.3-localci' 8 | 9 | Write-Output '***** Recreating artifacts directory...' 10 | $artifactPath = '.\artifacts' 11 | if (Test-Path -Path $artifactPath) { 12 | Remove-Item -Path $artifactPath -Recurse -Force 13 | } 14 | 15 | 16 | & .\build\build.ps1 17 | 18 | & .\build\test.ps1 19 | 20 | & .\build\publish.ps1 21 | 22 | 23 | Write-Output '***** Done! Press any key to continue...' 24 | Read-Host | Out-Null 25 | -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/App.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Windows; 4 | using RadeonSoftwareSlimmer.Services; 5 | using RadeonSoftwareSlimmer.ViewModels; 6 | 7 | namespace RadeonSoftwareSlimmer 8 | { 9 | public partial class App : Application 10 | { 11 | protected override void OnStartup(StartupEventArgs e) 12 | { 13 | base.OnStartup(e); 14 | 15 | SetupExceptionHandling(); 16 | 17 | ThemeService.SetThemeToUserSettings(new WindowsRegistry()); 18 | } 19 | 20 | 21 | private void SetupExceptionHandling() 22 | { 23 | AppDomain.CurrentDomain.UnhandledException += (sender, ex) => LogUnhandledException((Exception)ex.ExceptionObject); 24 | 25 | DispatcherUnhandledException += (sender, ex) => 26 | { 27 | LogUnhandledException(ex.Exception); 28 | ex.Handled = true; 29 | }; 30 | 31 | TaskScheduler.UnobservedTaskException += (sender, ex) => 32 | { 33 | LogUnhandledException(ex.Exception); 34 | ex.SetObserved(); 35 | }; 36 | } 37 | 38 | private static void LogUnhandledException(Exception exception) 39 | { 40 | StaticViewModel.AddLogMessage(exception); 41 | StaticViewModel.IsLoading = false; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using System.Windows; 3 | 4 | [assembly: ThemeInfo( 5 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 6 | //(used if a resource is not found in the page, 7 | // or application resource dictionaries) 8 | ResourceDictionaryLocation.SourceAssembly) //where the generic resource dictionary is located 9 | //(used if a resource is not found in the page, 10 | // app, or any theme specific resource dictionaries) 11 | ] 12 | 13 | [assembly: InternalsVisibleTo("RadeonSoftwareSlimmer.Test")] -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Intefaces/IRegistry.cs: -------------------------------------------------------------------------------- 1 | namespace RadeonSoftwareSlimmer.Intefaces 2 | { 3 | public interface IRegistry 4 | { 5 | IRegistryKey CurrentUser { get; } 6 | IRegistryKey LocalMachine { get; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Intefaces/IRegistryKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Win32; 3 | 4 | namespace RadeonSoftwareSlimmer.Intefaces 5 | { 6 | public interface IRegistryKey : IDisposable 7 | { 8 | string Name { get; } 9 | 10 | 11 | IRegistryKey OpenSubKey(string name, bool writable); 12 | 13 | string[] GetSubKeyNames(); 14 | 15 | 16 | object GetValue(string name); 17 | 18 | object GetValue(string name, object defaultValue); 19 | 20 | void SetValue(string name, object value, RegistryValueKind valueKind); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  15 | 16 | 17 | 18 | 26 | 27 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Views/HelpLink.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | 6 | namespace RadeonSoftwareSlimmer.Views 7 | { 8 | public partial class HelpLink : UserControl 9 | { 10 | public static readonly DependencyProperty LinkProperty = DependencyProperty.Register(nameof(Link), typeof(Uri), typeof(MainWindow)); 11 | 12 | 13 | public HelpLink() 14 | { 15 | InitializeComponent(); 16 | } 17 | 18 | 19 | public Uri Link 20 | { 21 | get { return (Uri)GetValue(LinkProperty); } 22 | set 23 | { 24 | SetValue(LinkProperty, value); 25 | btnLink.ToolTip = $"Click to open wiki page for help on this topic: {value?.AbsoluteUri}"; 26 | } 27 | } 28 | 29 | 30 | private void Button_Click(object sender, RoutedEventArgs e) 31 | { 32 | ProcessStartInfo startInfo = new ProcessStartInfo(Link.AbsoluteUri); 33 | startInfo.UseShellExecute = true; 34 | 35 | using (Process process = new Process()) 36 | { 37 | process.StartInfo = startInfo; 38 | process.Start(); 39 | } 40 | 41 | e.Handled = true; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Views/LoggingView.xaml: -------------------------------------------------------------------------------- 1 |  13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 40 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Views/LoggingView.xaml.cs: -------------------------------------------------------------------------------- 1 | using RadeonSoftwareSlimmer.ViewModels; 2 | 3 | namespace RadeonSoftwareSlimmer.Views 4 | { 5 | public partial class LoggingView : System.Windows.Controls.UserControl 6 | { 7 | public LoggingView() 8 | { 9 | InitializeComponent(); 10 | } 11 | 12 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S2325:Methods and properties that don't access instance data should be static", Justification = "WPF event handlers cannot be static.")] 13 | private void btnSaveLogs_Click(object sender, System.Windows.RoutedEventArgs e) 14 | { 15 | StaticViewModel.SaveLogs(); 16 | } 17 | 18 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S2325:Methods and properties that don't access instance data should be static", Justification = "WPF event handlers cannot be static.")] 19 | private void btnClearLogs_Click(object sender, System.Windows.RoutedEventArgs e) 20 | { 21 | StaticViewModel.ClearLogs(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Views/MessageView.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Views/MessageView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace RadeonSoftwareSlimmer.Views 4 | { 5 | public partial class MessageView : UserControl 6 | { 7 | public MessageView() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Views/PostInstallView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.IO.Abstractions; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | using RadeonSoftwareSlimmer.Services; 5 | using RadeonSoftwareSlimmer.ViewModels; 6 | 7 | namespace RadeonSoftwareSlimmer.Views 8 | { 9 | public partial class PostInstallView : UserControl 10 | { 11 | private readonly PostInstallViewModel _viewModel = new PostInstallViewModel(new FileSystem(), new WindowsRegistry()); 12 | 13 | 14 | public PostInstallView() 15 | { 16 | InitializeComponent(); 17 | DataContext = _viewModel; 18 | } 19 | 20 | private async void UserControl_Initialized(object sender, System.EventArgs e) 21 | { 22 | await _viewModel.LoadOrRefreshAsync(false); 23 | } 24 | 25 | 26 | private async void btnLoadOrRefresh_Click(object sender, RoutedEventArgs e) 27 | { 28 | await _viewModel.LoadOrRefreshAsync(true); 29 | } 30 | 31 | private async void btnApply_Click(object sender, RoutedEventArgs e) 32 | { 33 | await _viewModel.ApplyChangesAsync(); 34 | } 35 | 36 | 37 | private async void btnHostServicesRestart_Click(object sender, RoutedEventArgs e) 38 | { 39 | await _viewModel.HostServices_RestartAsync(); 40 | } 41 | 42 | private async void btnHostServicesStop_Click(object sender, RoutedEventArgs e) 43 | { 44 | await _viewModel.HostServices_StopAsync(); 45 | } 46 | 47 | 48 | private void btnScheduledTaskEnableAll_Click(object sender, RoutedEventArgs e) 49 | { 50 | _viewModel.ScheduledTask_SetAll(true); 51 | } 52 | 53 | private void btnScheduledTaskDisableAll_Click(object sender, RoutedEventArgs e) 54 | { 55 | _viewModel.ScheduledTask_SetAll(false); 56 | } 57 | 58 | 59 | private async void btnServiceStart_Click(object sender, RoutedEventArgs e) 60 | { 61 | await PostInstallViewModel.Service_StartAsync(grdServices.SelectedItem); 62 | } 63 | 64 | private async void btnServiceStop_Click(object sender, RoutedEventArgs e) 65 | { 66 | await PostInstallViewModel.Service_StopAsync(grdServices.SelectedItem); 67 | } 68 | 69 | private async void btnServiceChangeStartMode_Click(object sender, RoutedEventArgs e) 70 | { 71 | await PostInstallViewModel.Service_SetStartModeAsync(grdServices.SelectedItem, cbxServiceStartMode.Text); 72 | } 73 | 74 | private async void btnServiceDelete_Click(object sender, RoutedEventArgs e) 75 | { 76 | await PostInstallViewModel.Service_DeleteAsync(grdServices.SelectedItem); 77 | } 78 | 79 | 80 | private void btnTempFilesSelectAll_Click(object sender, RoutedEventArgs e) 81 | { 82 | _viewModel.TempFilesSetAll(true); 83 | } 84 | 85 | private void btnTempFilesSelectNone_Click(object sender, RoutedEventArgs e) 86 | { 87 | _viewModel.TempFilesSetAll(false); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/Views/PreInstallView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.IO.Abstractions; 2 | using System.Threading.Tasks; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using RadeonSoftwareSlimmer.ViewModels; 6 | 7 | namespace RadeonSoftwareSlimmer.Views 8 | { 9 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 10 | public partial class PreInstallView : UserControl 11 | { 12 | private readonly PreInstallViewModel _viewModel = new PreInstallViewModel(new FileSystem()); 13 | 14 | 15 | public PreInstallView() 16 | { 17 | InitializeComponent(); 18 | DataContext = _viewModel; 19 | } 20 | 21 | private async Task UpdateWizardIndexAsync() 22 | { 23 | //Binding this doesn't work :( 24 | flpWizard.SelectedIndex = (int)_viewModel.FlipViewIndex; 25 | 26 | if (_viewModel.FlipViewIndex == PreInstallViewModel.WizardIndex.ExtractingInstaller) 27 | { 28 | await _viewModel.ExtractInstallerFilesAsync(); 29 | await UpdateWizardIndexAsync(); 30 | } 31 | 32 | if (_viewModel.FlipViewIndex == PreInstallViewModel.WizardIndex.ModifyInstaller) 33 | { 34 | _viewModel.ReadFromExtractedInstaller(); 35 | } 36 | } 37 | 38 | 39 | private async void btnSkip0_Click(object sender, RoutedEventArgs e) 40 | { 41 | _viewModel.SkipInstallFile(); 42 | await UpdateWizardIndexAsync(); 43 | } 44 | 45 | private void btnInstallerFileBrowse_Click(object sender, RoutedEventArgs e) 46 | { 47 | _viewModel.BrowseForInstallerFile(); 48 | } 49 | 50 | private async void btnNext0_Click(object sender, RoutedEventArgs e) 51 | { 52 | _viewModel.ValidateInstallerFile(); 53 | await UpdateWizardIndexAsync(); 54 | } 55 | 56 | 57 | private async void btnBack1_Click(object sender, RoutedEventArgs e) 58 | { 59 | _viewModel.Back(); 60 | await UpdateWizardIndexAsync(); 61 | } 62 | 63 | private void btnExtractLocatonBrowse_Click(object sender, RoutedEventArgs e) 64 | { 65 | _viewModel.BrowseForExtractLocation(); 66 | } 67 | 68 | private async void btnNext1_Click(object sender, RoutedEventArgs e) 69 | { 70 | _viewModel.ValidateExtractLocation(); 71 | await UpdateWizardIndexAsync(); 72 | } 73 | 74 | 75 | private void btnModifyInstallerFiles_Click(object sender, RoutedEventArgs e) 76 | { 77 | _viewModel.ModifyInstaller(); 78 | } 79 | 80 | private void btnResetToDefault_Click(object sender, RoutedEventArgs e) 81 | { 82 | _viewModel.ResetInstallerToDefaults(); 83 | } 84 | 85 | private void btnRunInstaller_Click(object sender, RoutedEventArgs e) 86 | { 87 | _viewModel.RunRadeonSoftwareSetup(); 88 | Window.GetWindow(this).Close(); 89 | } 90 | 91 | private void btnRunCleanup_Click(object sender, RoutedEventArgs e) 92 | { 93 | _viewModel.RunAmdCleanupUtility(); 94 | Window.GetWindow(this).Close(); 95 | } 96 | 97 | private async void btnNewInstaller_Click(object sender, RoutedEventArgs e) 98 | { 99 | _viewModel.SelectNewInstaller(); 100 | await UpdateWizardIndexAsync(); 101 | } 102 | 103 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S2325:Methods and properties that don't access instance data should be static", Justification = "WPF event handlers cannot be static.")] 104 | private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) 105 | { 106 | //Stop these DataGrid SelectionChanged events from triggering the SelectionChanged even on the FlipView 107 | e.Handled = true; 108 | } 109 | 110 | 111 | private void btnPackageSelectAll_Click(object sender, RoutedEventArgs e) 112 | { 113 | _viewModel.Packages_SetAll(true); 114 | } 115 | private void btnPackageSelectNone_Click(object sender, RoutedEventArgs e) 116 | { 117 | _viewModel.Packages_SetAll(false); 118 | } 119 | 120 | private void btnScheduledTaskSelectAll_Click(object sender, RoutedEventArgs e) 121 | { 122 | _viewModel.ScheduledTask_SetAll(true); 123 | } 124 | private void btnScheduledTaskSelectNone_Click(object sender, RoutedEventArgs e) 125 | { 126 | _viewModel.ScheduledTask_SetAll(false); 127 | } 128 | 129 | private void btnDisplayComponentsSelectAll_Click(object sender, RoutedEventArgs e) 130 | { 131 | _viewModel.DisplayComponents_SetAll(true); 132 | } 133 | private void btnDisplayComponentsSelectNone_Click(object sender, RoutedEventArgs e) 134 | { 135 | _viewModel.DisplayComponents_SetAll(false); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 59 | 60 | 61 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/RadeonSoftwareSlimmer/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSDragoon/RadeonSoftwareSlimmer/86cfef280a29539dc28c64b13a52d06374af46e4/src/RadeonSoftwareSlimmer/icon.ico -------------------------------------------------------------------------------- /src/Shared/7-Zip/7z.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSDragoon/RadeonSoftwareSlimmer/86cfef280a29539dc28c64b13a52d06374af46e4/src/Shared/7-Zip/7z.dll -------------------------------------------------------------------------------- /src/Shared/7-Zip/7z.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSDragoon/RadeonSoftwareSlimmer/86cfef280a29539dc28c64b13a52d06374af46e4/src/Shared/7-Zip/7z.exe -------------------------------------------------------------------------------- /src/Shared/7-Zip/License.txt: -------------------------------------------------------------------------------- 1 | 7-Zip 2 | ~~~~~ 3 | License for use and distribution 4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | 7-Zip Copyright (C) 1999-2024 Igor Pavlov. 7 | 8 | The licenses for files are: 9 | 10 | - 7z.dll: 11 | - The "GNU LGPL" as main license for most of the code 12 | - The "GNU LGPL" with "unRAR license restriction" for some code 13 | - The "BSD 3-clause License" for some code 14 | - The "BSD 2-clause License" for some code 15 | - All other files: the "GNU LGPL". 16 | 17 | Redistributions in binary form must reproduce related license information from this file. 18 | 19 | Note: 20 | You can use 7-Zip on any computer, including a computer in a commercial 21 | organization. You don't need to register or pay for 7-Zip. 22 | 23 | 24 | GNU LGPL information 25 | -------------------- 26 | 27 | This library is free software; you can redistribute it and/or 28 | modify it under the terms of the GNU Lesser General Public 29 | License as published by the Free Software Foundation; either 30 | version 2.1 of the License, or (at your option) any later version. 31 | 32 | This library is distributed in the hope that it will be useful, 33 | but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 35 | Lesser General Public License for more details. 36 | 37 | You can receive a copy of the GNU Lesser General Public License from 38 | http://www.gnu.org/ 39 | 40 | 41 | 42 | 43 | BSD 3-clause License in 7-Zip code 44 | ---------------------------------- 45 | 46 | The "BSD 3-clause License" is used for the following code in 7z.dll 47 | 1) LZFSE data decompression. 48 | That code was derived from the code in the "LZFSE compression library" developed by Apple Inc, 49 | that also uses the "BSD 3-clause License". 50 | 2) ZSTD data decompression. 51 | that code was developed using original zstd decoder code as reference code. 52 | The original zstd decoder code was developed by Facebook Inc, 53 | that also uses the "BSD 3-clause License". 54 | 55 | Copyright (c) 2015-2016, Apple Inc. All rights reserved. 56 | Copyright (c) Facebook, Inc. All rights reserved. 57 | Copyright (c) 2023-2024 Igor Pavlov. 58 | 59 | Text of the "BSD 3-clause License" 60 | ---------------------------------- 61 | 62 | Redistribution and use in source and binary forms, with or without modification, 63 | are permitted provided that the following conditions are met: 64 | 65 | 1. Redistributions of source code must retain the above copyright notice, this 66 | list of conditions and the following disclaimer. 67 | 68 | 2. Redistributions in binary form must reproduce the above copyright notice, 69 | this list of conditions and the following disclaimer in the documentation 70 | and/or other materials provided with the distribution. 71 | 72 | 3. Neither the name of the copyright holder nor the names of its contributors may 73 | be used to endorse or promote products derived from this software without 74 | specific prior written permission. 75 | 76 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 77 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 78 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 79 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 80 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 81 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 82 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 83 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 84 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 85 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 86 | 87 | --- 88 | 89 | 90 | 91 | 92 | BSD 2-clause License in 7-Zip code 93 | ---------------------------------- 94 | 95 | The "BSD 2-clause License" is used for the XXH64 code in 7-Zip. 96 | 97 | XXH64 code in 7-Zip was derived from the original XXH64 code developed by Yann Collet. 98 | 99 | Copyright (c) 2012-2021 Yann Collet. 100 | Copyright (c) 2023-2024 Igor Pavlov. 101 | 102 | Text of the "BSD 2-clause License" 103 | ---------------------------------- 104 | 105 | Redistribution and use in source and binary forms, with or without modification, 106 | are permitted provided that the following conditions are met: 107 | 108 | 1. Redistributions of source code must retain the above copyright notice, this 109 | list of conditions and the following disclaimer. 110 | 111 | 2. Redistributions in binary form must reproduce the above copyright notice, 112 | this list of conditions and the following disclaimer in the documentation 113 | and/or other materials provided with the distribution. 114 | 115 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 116 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 117 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 118 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 119 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 120 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 121 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 122 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 123 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 124 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 125 | 126 | --- 127 | 128 | 129 | 130 | 131 | unRAR license restriction 132 | ------------------------- 133 | 134 | The decompression engine for RAR archives was developed using source 135 | code of unRAR program. 136 | All copyrights to original unRAR code are owned by Alexander Roshal. 137 | 138 | The license for original unRAR code has the following restriction: 139 | 140 | The unRAR sources cannot be used to re-create the RAR compression algorithm, 141 | which is proprietary. Distribution of modified unRAR sources in separate form 142 | or as a part of other software is permitted, provided that it is clearly 143 | stated in the documentation and source comments that the code may 144 | not be used to develop a RAR (WinRAR) compatible archiver. 145 | 146 | -- 147 | -------------------------------------------------------------------------------- /src/Shared/Shared.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 9b80e4b0-8113-4fd6-a3b2-f67e98604f6c 7 | 8 | 9 | ThirdPartyApplications 10 | 11 | 12 | 13 | PreserveNewest 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Shared/Shared.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9b80e4b0-8113-4fd6-a3b2-f67e98604f6c 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | PreserveNewest 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/Models/PostInstall/HostServicesModelTests.cs: -------------------------------------------------------------------------------- 1 | using System.IO.Abstractions.TestingHelpers; 2 | using NUnit.Framework; 3 | using RadeonSoftwareSlimmer.Models.PostInstall; 4 | using RadeonSoftwareSlimmer.Test.TestDoubles; 5 | 6 | namespace RadeonSoftwareSlimmer.Test.Models.PostInstall 7 | { 8 | public class HostServicesModelTests 9 | { 10 | private MockFileSystem _fileSystem; 11 | private FakeRegistry _registry; 12 | 13 | [SetUp] 14 | public void Setup() 15 | { 16 | _fileSystem = new MockFileSystem(); 17 | _registry = new FakeRegistry(); 18 | } 19 | 20 | 21 | [Test] 22 | public void Ctor_InstalledIsFalse() 23 | { 24 | HostServiceModel hostServiceModel = new HostServiceModel(_fileSystem, _registry); 25 | 26 | Assert.That(hostServiceModel.Installed, Is.False); 27 | } 28 | 29 | 30 | [Test] 31 | public void LoadOrRefresh_MissingAMDRegistryKeyFileDoNotExist_InstalledIsFalse() 32 | { 33 | _registry.MockLocalMachine.AddTestSubKey("SOFTWARE"); 34 | _fileSystem.AddDirectory(@"C:\Program Files"); 35 | HostServiceModel hostServiceModel = new HostServiceModel(_fileSystem, _registry); 36 | 37 | hostServiceModel.LoadOrRefresh(); 38 | 39 | Assert.That(hostServiceModel.Installed, Is.False); 40 | } 41 | 42 | [Test] 43 | public void LoadOrRefresh_MissingCNRegistryKeyFileDoNotExist_InstalledIsFalse() 44 | { 45 | _registry.MockLocalMachine.AddTestSubKey("SOFTWARE").AddTestSubKey("AMD"); 46 | _fileSystem.AddDirectory(@"C:\Program Files"); 47 | HostServiceModel hostServiceModel = new HostServiceModel(_fileSystem, _registry); 48 | 49 | hostServiceModel.LoadOrRefresh(); 50 | 51 | Assert.That(hostServiceModel.Installed, Is.False); 52 | } 53 | 54 | [Test] 55 | public void LoadOrRefresh_MissingInstallDirValueFileDoNotExist_InstalledIsFalse() 56 | { 57 | _registry.MockLocalMachine.AddTestSubKey("SOFTWARE").AddTestSubKey("AMD").AddTestSubKey("CN"); 58 | _fileSystem.AddDirectory(@"C:\Program Files"); 59 | HostServiceModel hostServiceModel = new HostServiceModel(_fileSystem, _registry); 60 | 61 | hostServiceModel.LoadOrRefresh(); 62 | 63 | Assert.That(hostServiceModel.Installed, Is.False); 64 | } 65 | 66 | [Test] 67 | public void LoadOrRefresh_RegistryValueExistsDirectoryDoesNotExist_InstalledIsFalse() 68 | { 69 | // I believe this is the exact scenario for this issue 70 | // https://github.com/GSDragoon/RadeonSoftwareSlimmer/discussions/37 71 | _registry.MockLocalMachine.AddTestSubKey("SOFTWARE").AddTestSubKey("AMD").AddTestSubKey("CN"). 72 | AddTestValue("InstallDir", @"C:\Program Files\AMD\CNext\CNext\"); 73 | _fileSystem.AddDirectory(@"C:\Program Files"); 74 | HostServiceModel hostServiceModel = new HostServiceModel(_fileSystem, _registry); 75 | 76 | hostServiceModel.LoadOrRefresh(); 77 | 78 | Assert.That(hostServiceModel.Installed, Is.False); 79 | } 80 | 81 | [Test] 82 | public void LoadOrRefresh_RegistryValueExistsFileDoesNotExist_InstalledIsFalse() 83 | { 84 | _registry.MockLocalMachine.AddTestSubKey("SOFTWARE").AddTestSubKey("AMD").AddTestSubKey("CN"). 85 | AddTestValue("InstallDir", @"C:\Program Files\AMD\CNext\CNext\"); 86 | _fileSystem.AddDirectory(@"C:\Program Files\AMD\CNext\CNext"); 87 | HostServiceModel hostServiceModel = new HostServiceModel(_fileSystem, _registry); 88 | 89 | hostServiceModel.LoadOrRefresh(); 90 | 91 | Assert.That(hostServiceModel.Installed, Is.False); 92 | } 93 | 94 | [Test] 95 | public void LoadOrRefresh_RegistryValueExistsFileExists_InstalledIsTrue() 96 | { 97 | _registry.MockLocalMachine.AddTestSubKey("SOFTWARE").AddTestSubKey("AMD").AddTestSubKey("CN"). 98 | AddTestValue("InstallDir", @"C:\Program Files\AMD\CNext\CNext\"); 99 | _fileSystem.AddDirectory(@"C:\Program Files\AMD\CNext\CNext"); 100 | _fileSystem.AddEmptyFile(@"C:\Program Files\AMD\CNext\CNext\cncmd.exe"); 101 | HostServiceModel hostServiceModel = new HostServiceModel(_fileSystem, _registry); 102 | 103 | hostServiceModel.LoadOrRefresh(); 104 | 105 | Assert.That(hostServiceModel.Installed, Is.True); 106 | } 107 | 108 | [Test] 109 | public void LoadOrRefresh_MissingRegistryKeyDefaultFileExist_InstalledIsTrue() 110 | { 111 | _registry.MockLocalMachine.AddTestSubKey("SOFTWARE"); 112 | _fileSystem.AddDirectory(@"C:\Program Files"); 113 | _fileSystem.AddDirectory(@"C:\Program Files\AMD\CNext\CNext"); 114 | _fileSystem.AddEmptyFile(@"C:\Program Files\AMD\CNext\CNext\cncmd.exe"); 115 | 116 | HostServiceModel hostServiceModel = new HostServiceModel(_fileSystem, _registry); 117 | 118 | hostServiceModel.LoadOrRefresh(); 119 | 120 | Assert.That(hostServiceModel.Installed, Is.True); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/Models/PostInstall/InstalledModelTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using NUnit.Framework; 4 | using RadeonSoftwareSlimmer.Models.PostInstall; 5 | using RadeonSoftwareSlimmer.Test.TestDoubles; 6 | 7 | namespace RadeonSoftwareSlimmer.Test.Models.PostInstall 8 | { 9 | public class InstalledModelTests 10 | { 11 | [Test] 12 | public void Ctor_LoadsRegistryValues() 13 | { 14 | FakeRegistryKey installKey = new FakeRegistryKey() 15 | .AddTestValue("DisplayName", "DisplayName Value") 16 | .AddTestValue("Publisher", "Publisher Value") 17 | .AddTestValue("DisplayVersion", "DisplayVersion Value") 18 | .AddTestValue("UninstallString", "UninstallString Value") 19 | .AddTestValue("WindowsInstaller", 0); 20 | 21 | InstalledModel installedModel = new InstalledModel(installKey, "Test"); 22 | 23 | Assert.Multiple(() => 24 | { 25 | Assert.That(installedModel, Is.Not.Null); 26 | Assert.That(installedModel.Uninstall, Is.False); 27 | 28 | Assert.That(installedModel.ProductCode, Is.EqualTo("Test")); 29 | Assert.That(installedModel.DisplayName, Is.EqualTo("DisplayName Value")); 30 | Assert.That(installedModel.Publisher, Is.EqualTo("Publisher Value")); 31 | Assert.That(installedModel.DisplayVersion, Is.EqualTo("DisplayVersion Value")); 32 | Assert.That(installedModel.UninstallCommand, Is.EqualTo("UninstallString Value")); 33 | }); 34 | } 35 | 36 | [Test] 37 | [System.Diagnostics.CodeAnalysis.SuppressMessage("System.IO.Abstractions", "IO0006:Replace Path class with IFileSystem.Path for improved testability", Justification = "Just combining a path")] 38 | public void Ctor_MsiInstaller_GeneratesUninstallCommand() 39 | { 40 | string keyName = Guid.NewGuid().ToString("B"); 41 | FakeRegistryKey installKey = new FakeRegistryKey() 42 | .SetTestName(keyName) 43 | .AddTestValue("UninstallString", "UninstallString Value") 44 | .AddTestValue("WindowsInstaller", 1); 45 | 46 | InstalledModel installedModel = new InstalledModel(installKey, keyName); 47 | 48 | Assert.Multiple(() => 49 | { 50 | Assert.That(installedModel, Is.Not.Null); 51 | Assert.That(installedModel.Uninstall, Is.False); 52 | 53 | Assert.That(installedModel.ProductCode, Is.EqualTo(keyName)); 54 | string msiexec = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System, Environment.SpecialFolderOption.DoNotVerify), "msiexec.exe"); 55 | Assert.That(installedModel.UninstallCommand, Is.EqualTo($"{msiexec} /uninstall {keyName}")); 56 | }); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/Models/PostInstall/WindowsAppStartupModelTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using NUnit.Framework; 3 | using RadeonSoftwareSlimmer.Models.PostInstall; 4 | using RadeonSoftwareSlimmer.Test.TestDoubles; 5 | 6 | namespace RadeonSoftwareSlimmer.Test.Models.PostInstall 7 | { 8 | public class WindowsAppStartupModelTest 9 | { 10 | private static readonly string RSX_LAUNCHER_REG_PATH = @"Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\SystemAppData\AdvancedMicroDevicesInc-RSXCM_fhmx3h6dzfmvj\launcherrsxruntimeTask"; 11 | private static readonly string RSX_LAUNCHER_REG_STATUS_NAME = "State"; 12 | private static readonly string RSX_LAUNCHER_REG_LASTDISABLEDTIME_NAME = "LastDisabledTime"; 13 | private static readonly object STATE_ENABLED_VALUE = 2; 14 | private static readonly object STATE_DISABLED_VALUE = 1; 15 | private static readonly string RSX_LAUNCHER_REG_STARTUPONCE_NAME = "UserEnabledStartupOnce"; 16 | private static readonly object STATE_STARTUPONCE_YES = 1; 17 | private static readonly object STATE_STARTUPONCE_NO = 0; 18 | 19 | 20 | [Test] 21 | public void LoadStartupSettings_KeyDoesNotExist_SetsExistsToFalse() 22 | { 23 | FakeRegistry dummyRegistry = new FakeRegistry(); 24 | dummyRegistry.MockCurrentUser.AddTestSubKey(@"Some\other\key\path"); 25 | WindowsAppStartupModel appStartup = new WindowsAppStartupModel(dummyRegistry); 26 | 27 | appStartup.LoadOrRefresh(); 28 | 29 | Assert.That(appStartup.Exists, Is.False); 30 | } 31 | 32 | [Test] 33 | public void LoadStartupSettings_KeyDoesExist_SetsExistsToTrue() 34 | { 35 | FakeRegistry dummyRegistry = new FakeRegistry(); 36 | dummyRegistry.MockCurrentUser.AddTestSubKey(RSX_LAUNCHER_REG_PATH); 37 | WindowsAppStartupModel appStartup = new WindowsAppStartupModel(dummyRegistry); 38 | 39 | appStartup.LoadOrRefresh(); 40 | 41 | Assert.That(appStartup.Exists, Is.True); 42 | } 43 | 44 | [Test] 45 | public void LoadStartupSettings_StateIsEnabled_SetsEnabledToTrue() 46 | { 47 | FakeRegistry dummyRegistry = new FakeRegistry(); 48 | dummyRegistry.MockCurrentUser.AddTestSubKey(RSX_LAUNCHER_REG_PATH) 49 | .AddTestValue(RSX_LAUNCHER_REG_STATUS_NAME, STATE_ENABLED_VALUE) 50 | .AddTestValue(RSX_LAUNCHER_REG_STARTUPONCE_NAME, STATE_STARTUPONCE_YES); 51 | WindowsAppStartupModel appStartup = new WindowsAppStartupModel(dummyRegistry); 52 | 53 | appStartup.LoadOrRefresh(); 54 | 55 | Assert.Multiple(() => 56 | { 57 | Assert.That(appStartup.Exists, Is.True); 58 | Assert.That(appStartup.Enabled, Is.True); 59 | }); 60 | } 61 | 62 | [Test] 63 | public void LoadStartupSettings_StateIsDisabled_SetsEnabledToFalse() 64 | { 65 | FakeRegistry dummyRegistry = new FakeRegistry(); 66 | dummyRegistry.MockCurrentUser.AddTestSubKey(RSX_LAUNCHER_REG_PATH) 67 | .AddTestValue(RSX_LAUNCHER_REG_STATUS_NAME, STATE_DISABLED_VALUE) 68 | .AddTestValue(RSX_LAUNCHER_REG_STARTUPONCE_NAME, STATE_STARTUPONCE_YES); 69 | WindowsAppStartupModel appStartup = new WindowsAppStartupModel(dummyRegistry); 70 | 71 | appStartup.LoadOrRefresh(); 72 | 73 | Assert.Multiple(() => 74 | { 75 | Assert.That(appStartup.Exists, Is.True); 76 | Assert.That(appStartup.Enabled, Is.False); 77 | }); 78 | } 79 | 80 | [Test] 81 | public void LoadStartupSettings_StateIsDisabledNotEnabledOnce_SetsEnabledToTrue() 82 | { 83 | FakeRegistry dummyRegistry = new FakeRegistry(); 84 | dummyRegistry.MockCurrentUser.AddTestSubKey(RSX_LAUNCHER_REG_PATH) 85 | .AddTestValue(RSX_LAUNCHER_REG_STATUS_NAME, STATE_DISABLED_VALUE) 86 | .AddTestValue(RSX_LAUNCHER_REG_STARTUPONCE_NAME, STATE_STARTUPONCE_NO); 87 | WindowsAppStartupModel appStartup = new WindowsAppStartupModel(dummyRegistry); 88 | 89 | appStartup.LoadOrRefresh(); 90 | 91 | Assert.Multiple(() => 92 | { 93 | Assert.That(appStartup.Exists, Is.True); 94 | Assert.That(appStartup.Enabled, Is.True); 95 | }); 96 | } 97 | 98 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Major Code Smell", "S4144:Methods should not have identical implementations", Justification = "Sonar analyzers are wrong")] 99 | [Test] 100 | public void LoadStartupSettings_StateIsDisabledEnabledOnce_SetsEnabledToFalse() 101 | { 102 | FakeRegistry dummyRegistry = new FakeRegistry(); 103 | dummyRegistry.MockCurrentUser.AddTestSubKey(RSX_LAUNCHER_REG_PATH) 104 | .AddTestValue(RSX_LAUNCHER_REG_STATUS_NAME, STATE_DISABLED_VALUE) 105 | .AddTestValue(RSX_LAUNCHER_REG_STARTUPONCE_NAME, STATE_STARTUPONCE_YES); 106 | WindowsAppStartupModel appStartup = new WindowsAppStartupModel(dummyRegistry); 107 | 108 | appStartup.LoadOrRefresh(); 109 | 110 | Assert.Multiple(() => 111 | { 112 | Assert.That(appStartup.Exists, Is.True); 113 | Assert.That(appStartup.Enabled, Is.False); 114 | }); 115 | } 116 | 117 | 118 | 119 | [Test] 120 | public void Enable_SetsEnabledValues() 121 | { 122 | FakeRegistry dummyRegistry = new FakeRegistry(); 123 | dummyRegistry.MockCurrentUser.AddTestSubKey(RSX_LAUNCHER_REG_PATH) 124 | .AddTestValue(RSX_LAUNCHER_REG_STATUS_NAME, STATE_DISABLED_VALUE); 125 | WindowsAppStartupModel appStartup = new WindowsAppStartupModel(dummyRegistry); 126 | appStartup.Enabled = false; 127 | 128 | appStartup.Enable(); 129 | 130 | Assert.Multiple(() => 131 | { 132 | Assert.That(appStartup.Enabled, Is.True); 133 | 134 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values.ContainsKey(RSX_LAUNCHER_REG_STATUS_NAME), Is.True); 135 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values[RSX_LAUNCHER_REG_STATUS_NAME].Value, Is.EqualTo(STATE_ENABLED_VALUE)); 136 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values[RSX_LAUNCHER_REG_STATUS_NAME].Kind, Is.EqualTo(RegistryValueKind.DWord)); 137 | }); 138 | } 139 | 140 | [Test] 141 | public void Disable_SetsDisabledKeys() 142 | { 143 | FakeRegistry dummyRegistry = new FakeRegistry(); 144 | dummyRegistry.MockCurrentUser.AddTestSubKey(RSX_LAUNCHER_REG_PATH) 145 | .AddTestValue(RSX_LAUNCHER_REG_STATUS_NAME, STATE_ENABLED_VALUE); 146 | WindowsAppStartupModel appStartup = new WindowsAppStartupModel(dummyRegistry); 147 | appStartup.Enabled = false; 148 | 149 | appStartup.Disable(); 150 | 151 | Assert.Multiple(() => 152 | { 153 | Assert.That(appStartup.Enabled, Is.False); 154 | 155 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values.ContainsKey(RSX_LAUNCHER_REG_STATUS_NAME), Is.True); 156 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values[RSX_LAUNCHER_REG_STATUS_NAME].Value, Is.EqualTo(STATE_DISABLED_VALUE)); 157 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values[RSX_LAUNCHER_REG_STATUS_NAME].Kind, Is.EqualTo(RegistryValueKind.DWord)); 158 | 159 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values.ContainsKey(RSX_LAUNCHER_REG_STARTUPONCE_NAME), Is.True); 160 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values[RSX_LAUNCHER_REG_STARTUPONCE_NAME].Value, Is.EqualTo(STATE_STARTUPONCE_YES)); 161 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values[RSX_LAUNCHER_REG_STARTUPONCE_NAME].Kind, Is.EqualTo(RegistryValueKind.DWord)); 162 | 163 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values.ContainsKey(RSX_LAUNCHER_REG_LASTDISABLEDTIME_NAME), Is.True); 164 | Assert.That(dummyRegistry.MockCurrentUser.SubKeys[RSX_LAUNCHER_REG_PATH].Values[RSX_LAUNCHER_REG_LASTDISABLEDTIME_NAME].Kind, Is.EqualTo(RegistryValueKind.QWord)); 165 | }); 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/Models/PreInstall/PackageModelTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO.Abstractions; 2 | using System.IO.Abstractions.TestingHelpers; 3 | using NUnit.Framework; 4 | using RadeonSoftwareSlimmer.Models.PreInstall; 5 | 6 | namespace RadeonSoftwareSlimmer.Test.Models.PreInstall 7 | { 8 | public class PackageModelTest 9 | { 10 | private MockFileSystem _fileSystem; 11 | private IFileInfo _dummyFile; 12 | 13 | [SetUp] 14 | public void Setup() 15 | { 16 | string filePath = @"C:\Some\Path\To\A\File\foobar.json"; 17 | _fileSystem = new MockFileSystem(); 18 | _fileSystem.AddFile(filePath, new MockFileData(string.Empty)); 19 | _dummyFile = _fileSystem.FileInfo.New(filePath); 20 | } 21 | 22 | 23 | [Test] 24 | public void Ctor_DefaultsKeepToTrue() 25 | { 26 | PackageModel packageModel = new PackageModel(_dummyFile); 27 | 28 | Assert.That(packageModel.Keep, Is.True); 29 | } 30 | 31 | 32 | [Test] 33 | public void GetFile_ReturnsFile() 34 | { 35 | PackageModel packageModel = new PackageModel(_dummyFile); 36 | 37 | IFileInfo returnFile = packageModel.GetFile(); 38 | 39 | Assert.That(returnFile, Is.Not.Null); 40 | Assert.That(returnFile, Is.EqualTo(_dummyFile)); 41 | } 42 | 43 | 44 | [Test] 45 | public void Equals_SameProperties_ReturnsTrue() 46 | { 47 | PackageModel packageModel = new PackageModel(_dummyFile); 48 | packageModel.Keep = false; 49 | packageModel.ProductName = "Test Product Name"; 50 | packageModel.Url = "Test URL"; 51 | packageModel.Type = "Test Type"; 52 | packageModel.Description = "Test Description"; 53 | 54 | string filePath = @"C:\Some\Path\To\A\File\foobar.json"; 55 | MockFileSystem fileSystem = new MockFileSystem(); 56 | fileSystem.AddFile(filePath, new MockFileData(string.Empty)); 57 | IFileInfo dummyFile = _fileSystem.FileInfo.New(filePath); 58 | PackageModel duplicatePackageModel = new PackageModel(dummyFile); 59 | duplicatePackageModel.Keep = false; 60 | duplicatePackageModel.ProductName = "Test Product Name"; 61 | duplicatePackageModel.Url = "Test URL"; 62 | duplicatePackageModel.Type = "Test Type"; 63 | duplicatePackageModel.Description = "Test Description"; 64 | 65 | 66 | bool equals = packageModel.Equals(duplicatePackageModel); 67 | 68 | Assert.That(equals, Is.True); 69 | } 70 | 71 | [Test] 72 | public void Equals_DifferentProperties_ReturnsFalse() 73 | { 74 | PackageModel packageModel = new PackageModel(_dummyFile); 75 | packageModel.Keep = false; 76 | packageModel.ProductName = "Test Product Name"; 77 | packageModel.Url = "Test URL"; 78 | packageModel.Type = "Test Type"; 79 | packageModel.Description = "Test Description"; 80 | 81 | string filePath = @"C:\Some\Path\To\A\File\Differentfoobar.json"; 82 | MockFileSystem fileSystem = new MockFileSystem(); 83 | fileSystem.AddFile(filePath, new MockFileData(string.Empty)); 84 | IFileInfo dummyFile = _fileSystem.FileInfo.New(filePath); 85 | PackageModel duplicatePackageModel = new PackageModel(dummyFile); 86 | duplicatePackageModel.Keep = false; 87 | duplicatePackageModel.ProductName = "Different Test Product Name"; 88 | duplicatePackageModel.Url = "Different Test URL"; 89 | duplicatePackageModel.Type = "Different Test Type"; 90 | duplicatePackageModel.Description = "Different Test Description"; 91 | 92 | 93 | bool equals = packageModel.Equals(duplicatePackageModel); 94 | 95 | Assert.That(equals, Is.False); 96 | } 97 | 98 | [Test] 99 | public void Equals_IsNull_ReturnsFalse() 100 | { 101 | PackageModel packageModel = new PackageModel(_dummyFile); 102 | packageModel.Keep = false; 103 | packageModel.ProductName = "Test Product Name"; 104 | packageModel.Url = "Test URL"; 105 | packageModel.Type = "Test Type"; 106 | packageModel.Description = "Test Description"; 107 | 108 | 109 | bool equals = packageModel.Equals(null); 110 | 111 | Assert.That(equals, Is.False); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/Models/PreInstall/ScheduledTaskXmlModelTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO.Abstractions; 2 | using System.IO.Abstractions.TestingHelpers; 3 | using NUnit.Framework; 4 | using RadeonSoftwareSlimmer.Models.PreInstall; 5 | 6 | namespace RadeonSoftwareSlimmer.Test.Models.PreInstall 7 | { 8 | public class ScheduledTaskXmlModelTest 9 | { 10 | [Test] 11 | public void GetFile_ReturnsFile() 12 | { 13 | string filePath = @"C:\Some\path\To\A\file.xml"; 14 | MockFileSystem fileSystem = new MockFileSystem(); 15 | fileSystem.AddFile(filePath, new MockFileData(string.Empty)); 16 | IFileInfo originalFile = fileSystem.FileInfo.New(filePath); 17 | ScheduledTaskXmlModel scheduledTask = new ScheduledTaskXmlModel(originalFile); 18 | 19 | IFileInfo returnFile = scheduledTask.GetFile(); 20 | 21 | Assert.That(returnFile, Is.Not.Null); 22 | Assert.That(returnFile, Is.EqualTo(originalFile)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/RadeonSoftwareSlimmer.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Library 5 | 6 | 7 | 8 | 9 | all 10 | runtime; build; native; contentfiles; analyzers; buildtransitive 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | 17 | 18 | 19 | 20 | all 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | 23 | 24 | 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers; buildtransitive 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | PreserveNewest 39 | 40 | 41 | 42 | 43 | $(MSBuildProjectDirectory)\$(MSBuildProjectName).runsettings 44 | trx%3bLogFileName=$(MSBuildProjectName)_$(TargetFramework).trx 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/RadeonSoftwareSlimmer.Test.runsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute 8 | **/*.xaml,**/*.xaml.cs,AssemblyInfo.cs 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/Services/ProcessHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using NUnit.Framework; 3 | using RadeonSoftwareSlimmer.Services; 4 | 5 | namespace RadeonSoftwareSlimmer.Test.Services 6 | { 7 | [NonParallelizable] 8 | public class ProcessHandlerTests 9 | { 10 | [Test] 11 | public void RunProcess_NoArguments_Returns1() 12 | { 13 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\ping.exe"); 14 | Assert.That(processHandler.RunProcess(), Is.EqualTo(1)); 15 | } 16 | [Test] 17 | public void RunProcess_WithArguments_Returns0() 18 | { 19 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\ping.exe"); 20 | Assert.That(processHandler.RunProcess("localhost"), Is.EqualTo(0)); 21 | } 22 | [Test] 23 | public void RunProcess_DoesNotExist_ReturnsNegative1() 24 | { 25 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\DOES_NOT_EXIST.exe"); 26 | Assert.That(processHandler.RunProcess(), Is.EqualTo(-1)); 27 | } 28 | [Test] 29 | public void RunProcess_FileNameOnly_ReturnsNegative1() 30 | { 31 | ProcessHandler processHandler = new ProcessHandler("sc.exe"); 32 | Assert.That(processHandler.RunProcess(), Is.EqualTo(-1)); 33 | } 34 | 35 | [Test] 36 | public void IsProcessRunning_ProcessRunning_ReturnsTrue() 37 | { 38 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\svchost.exe"); 39 | Assert.That(processHandler.IsProcessRunning(), Is.True); 40 | } 41 | [Test] 42 | public void IsProcessRunning_ProcessNotRunning_ReturnsFalse() 43 | { 44 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\perfmon.exe"); 45 | Assert.That(processHandler.IsProcessRunning(), Is.False); 46 | } 47 | [Test] 48 | public void IsProcessRunning_DoesNotExist_ReturnsFalse() 49 | { 50 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\DOES_NOT_EXIST.exe"); 51 | Assert.That(processHandler.IsProcessRunning(), Is.False); 52 | } 53 | [Test] 54 | public void IsProcessRunning_FileNameOnly_ReturnsFalse() 55 | { 56 | ProcessHandler processHandler = new ProcessHandler("svchost.exe"); 57 | Assert.That(processHandler.IsProcessRunning(), Is.False); 58 | } 59 | 60 | [Test] 61 | public void WaitForProcessToEnd_NotRunning() 62 | { 63 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\tracert.exe"); 64 | processHandler.WaitForProcessToEnd(5); 65 | Assert.That(processHandler.IsProcessRunning(), Is.False); 66 | } 67 | [Test] 68 | public void WaitForProcessToEnd_EndsInTime() 69 | { 70 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\ping.exe"); 71 | using (Process process = new Process()) 72 | { 73 | process.StartInfo.FileName = @"C:\Windows\System32\ping.exe"; 74 | process.StartInfo.Arguments = "localhost"; 75 | process.StartInfo.UseShellExecute = false; 76 | process.StartInfo.CreateNoWindow = true; 77 | process.Start(); 78 | } 79 | 80 | processHandler.WaitForProcessToEnd(5); 81 | Assert.That(processHandler.IsProcessRunning(), Is.False); 82 | } 83 | [Test] 84 | public void WaitForProcessToEnd_ForcedKilled() 85 | { 86 | ProcessHandler processHandler = new ProcessHandler(@"C:\Windows\System32\ping.exe"); 87 | using (Process process = new Process()) 88 | { 89 | process.StartInfo.FileName = @"C:\Windows\System32\ping.exe"; 90 | process.StartInfo.Arguments = "localhost -n 10"; 91 | process.StartInfo.UseShellExecute = false; 92 | process.StartInfo.CreateNoWindow = true; 93 | process.Start(); 94 | } 95 | 96 | processHandler.WaitForProcessToEnd(5); 97 | Assert.That(processHandler.IsProcessRunning(), Is.False); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestData/PackageModel_cccmanifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Packages": { 3 | "Package": [ 4 | { 5 | "Info": { 6 | "Description": "Test Description", 7 | "productName": "Test productName", 8 | "url": "\\Parent\\child\\file.extension", 9 | "ptype": "Test ptype" 10 | } 11 | }, 12 | { 13 | "Info": { 14 | "Description": "Test2 Description", 15 | "productName": "Test2 productName", 16 | "url": "\\Parent2\\child2\\file2.extension", 17 | "ptype": "Test2 ptype" 18 | } 19 | } 20 | ] 21 | } 22 | } -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestData/PackageModel_installmanifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Packages": { 3 | "Package": [ 4 | { 5 | "Info": { 6 | "Description": "Test Description", 7 | "productName": "ZTest productName", 8 | "url": "\\Parent\\child\\file.extension", 9 | "ptype": "Test ptype" 10 | } 11 | }, 12 | { 13 | "Info": { 14 | "Description": "Test2 Description", 15 | "productName": "ATest2 productName", 16 | "url": "\\Parent2\\child2\\file2.extension", 17 | "ptype": "Test2 ptype" 18 | } 19 | } 20 | ] 21 | } 22 | } -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_Task10.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSDragoon/RadeonSoftwareSlimmer/86cfef280a29539dc28c64b13a52d06374af46e4/test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_Task10.xml -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_Task7.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSDragoon/RadeonSoftwareSlimmer/86cfef280a29539dc28c64b13a52d06374af46e4/test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_Task7.xml -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_TaskDisabled.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSDragoon/RadeonSoftwareSlimmer/86cfef280a29539dc28c64b13a52d06374af46e4/test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_TaskDisabled.xml -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_TaskEnabled.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSDragoon/RadeonSoftwareSlimmer/86cfef280a29539dc28c64b13a52d06374af46e4/test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_TaskEnabled.xml -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_TaskVista.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GSDragoon/RadeonSoftwareSlimmer/86cfef280a29539dc28c64b13a52d06374af46e4/test/RadeonSoftwareSlimmer.Test/TestData/ScheduledTaskXmlListModel_TaskVista.xml -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestDoubles/FakeRegistry.cs: -------------------------------------------------------------------------------- 1 | using RadeonSoftwareSlimmer.Intefaces; 2 | 3 | namespace RadeonSoftwareSlimmer.Test.TestDoubles 4 | { 5 | public class FakeRegistry : IRegistry 6 | { 7 | public FakeRegistry() 8 | { 9 | MockCurrentUser = new FakeRegistryKey(); 10 | MockLocalMachine = new FakeRegistryKey(); 11 | } 12 | 13 | public FakeRegistryKey MockCurrentUser { get; } 14 | public FakeRegistryKey MockLocalMachine { get; } 15 | 16 | 17 | public IRegistryKey CurrentUser => MockCurrentUser; 18 | 19 | public IRegistryKey LocalMachine => MockLocalMachine; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestDoubles/FakeRegistryKey.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Microsoft.Win32; 4 | using RadeonSoftwareSlimmer.Intefaces; 5 | 6 | namespace RadeonSoftwareSlimmer.Test.TestDoubles 7 | { 8 | public class FakeRegistryKey : IRegistryKey 9 | { 10 | private bool disposedValue; 11 | private string _name; 12 | 13 | public IDictionary Values { get; } 14 | public IDictionary SubKeys { get; } 15 | 16 | 17 | public FakeRegistryKey() 18 | { 19 | Values = new Dictionary(); 20 | SubKeys = new Dictionary(); 21 | _name = string.Empty; 22 | } 23 | 24 | 25 | #region Test Setup 26 | public FakeRegistryKey SetTestName(string name) 27 | { 28 | _name = name; 29 | return this; 30 | } 31 | 32 | public FakeRegistryKey AddTestValue(string name, object value) 33 | { 34 | return AddTestValue(name, value, RegistryValueKind.None); 35 | } 36 | public FakeRegistryKey AddTestValue(string name, object value, RegistryValueKind valueKind) 37 | { 38 | Values.Add(new KeyValuePair(name, new RegistryValue(value, valueKind))); 39 | return this; 40 | } 41 | 42 | public FakeRegistryKey AddTestSubKey(string name) 43 | { 44 | return AddTestSubKey(name, new FakeRegistryKey()); 45 | } 46 | public FakeRegistryKey AddTestSubKey(string name, FakeRegistryKey registryKey) 47 | { 48 | SubKeys.Add(name, registryKey); 49 | return registryKey; 50 | } 51 | #endregion 52 | 53 | 54 | #region IRegistryKey 55 | public string Name => _name; 56 | 57 | 58 | public void SetValue(string name, object value, RegistryValueKind valueKind) 59 | { 60 | if (Values.ContainsKey(name)) 61 | Values[name] = new RegistryValue(value, valueKind); 62 | else 63 | Values.Add(new KeyValuePair(name, new RegistryValue(value, valueKind))); 64 | } 65 | 66 | public object GetValue(string name) 67 | { 68 | return GetValue(name, null); 69 | } 70 | 71 | public object GetValue(string name, object defaultValue) 72 | { 73 | if (string.IsNullOrWhiteSpace(name)) 74 | return defaultValue; 75 | else if (Values.TryGetValue(name, out RegistryValue registryValue)) 76 | return registryValue.Value; 77 | else 78 | return defaultValue; 79 | } 80 | 81 | 82 | public IRegistryKey OpenSubKey(string name, bool writable) 83 | { 84 | if (string.IsNullOrWhiteSpace(name)) 85 | return null; 86 | else if (SubKeys.TryGetValue(name, out FakeRegistryKey fakeRegistryKey)) 87 | return fakeRegistryKey; 88 | else 89 | return null; 90 | } 91 | 92 | public string[] GetSubKeyNames() 93 | { 94 | return SubKeys.Keys.ToArray(); 95 | } 96 | #endregion 97 | 98 | 99 | protected virtual void Dispose(bool disposing) 100 | { 101 | if (!disposedValue) 102 | { 103 | if (disposing) 104 | { 105 | // dispose managed state (managed objects) 106 | } 107 | 108 | // free unmanaged resources (unmanaged objects) and override finalizer 109 | // set large fields to null 110 | disposedValue = true; 111 | } 112 | } 113 | 114 | public void Dispose() 115 | { 116 | // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method 117 | Dispose(disposing: true); 118 | System.GC.SuppressFinalize(this); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /test/RadeonSoftwareSlimmer.Test/TestDoubles/RegistryValue.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | 3 | namespace RadeonSoftwareSlimmer.Test.TestDoubles 4 | { 5 | public class RegistryValue 6 | { 7 | public RegistryValue(object value) 8 | { 9 | Value = value; 10 | Kind = RegistryValueKind.None; 11 | } 12 | 13 | public RegistryValue(object value, RegistryValueKind valueKind) 14 | { 15 | Value = value; 16 | Kind = valueKind; 17 | } 18 | 19 | public object Value { get; } 20 | public RegistryValueKind Kind { get; } 21 | } 22 | } 23 | --------------------------------------------------------------------------------