Unpacking Software Livestream

Join our monthly Unpacking Software livestream to hear about the latest news, chat and opinion on packaging, software deployment and lifecycle management!

Learn More

Chocolatey Product Spotlight

Join the Chocolatey Team on our regular monthly stream where we put a spotlight on the most recent Chocolatey product releases. You'll have a chance to have your questions answered in a live Ask Me Anything format.

Learn More

Chocolatey Coding Livestream

Join us for the Chocolatey Coding Livestream, where members of our team dive into the heart of open source development by coding live on various Chocolatey projects. Tune in to witness real-time coding, ask questions, and gain insights into the world of package management. Don't miss this opportunity to engage with our team and contribute to the future of Chocolatey!

Learn More

Calling All Chocolatiers! Whipping Up Windows Automation with Chocolatey Central Management

Webinar from
Wednesday, 17 January 2024

We are delighted to announce the release of Chocolatey Central Management v0.12.0, featuring seamless Deployment Plan creation, time-saving duplications, insightful Group Details, an upgraded Dashboard, bug fixes, user interface polishing, and refined documentation. As an added bonus we'll have members of our Solutions Engineering team on-hand to dive into some interesting ways you can leverage the new features available!

Watch On-Demand
Chocolatey Community Coffee Break

Join the Chocolatey Team as we discuss all things Community, what we do, how you can get involved and answer your Chocolatey questions.

Watch The Replays
Chocolatey and Intune Overview

Webinar Replay from
Wednesday, 30 March 2022

At Chocolatey Software we strive for simple, and teaching others. Let us teach you just how simple it could be to keep your 3rd party applications updated across your devices, all with Intune!

Watch On-Demand
Chocolatey For Business. In Azure. In One Click.

Livestream from
Thursday, 9 June 2022

Join James and Josh to show you how you can get the Chocolatey For Business recommended infrastructure and workflow, created, in Azure, in around 20 minutes.

Watch On-Demand
The Future of Chocolatey CLI

Livestream from
Thursday, 04 August 2022

Join Paul and Gary to hear more about the plans for the Chocolatey CLI in the not so distant future. We'll talk about some cool new features, long term asks from Customers and Community and how you can get involved!

Watch On-Demand
Hacktoberfest Tuesdays 2022

Livestreams from
October 2022

For Hacktoberfest, Chocolatey ran a livestream every Tuesday! Re-watch Cory, James, Gary, and Rain as they share knowledge on how to contribute to open-source projects such as Chocolatey CLI.

Watch On-Demand

Downloads:

584

Downloads of v 2.6.7:

16

Last Update:

01 Feb 2025

Package Maintainer(s):

Software Author(s):

  • Deco

Tags:

dlss nvidia gaming update-tool admin

DLSS Updater

  • 1
  • 2
  • 3

2.6.7 | Updated: 01 Feb 2025

Downloads:

584

Downloads of v 2.6.7:

16

Maintainer(s):

Software Author(s):

  • Deco

DLSS Updater 2.6.7

Legal Disclaimer: Neither this package nor Chocolatey Software, Inc. are affiliated with or endorsed by Deco. The inclusion of Deco trademark(s), if any, upon this webpage is solely to identify Deco goods or services and not for commercial purposes.

  • 1
  • 2
  • 3

Some Checks Have Failed or Are Not Yet Complete

Not All Tests Have Passed


Validation Testing Passed


Verification Testing Passed

Details

Scan Testing Resulted in Flagged as a Note:

At least one file within this package has greater than 0 detections, but less than 5

Details
Learn More

Deployment Method: Individual Install, Upgrade, & Uninstall

To install DLSS Updater, run the following command from the command line or from PowerShell:

>

To upgrade DLSS Updater, run the following command from the command line or from PowerShell:

>

To uninstall DLSS Updater, run the following command from the command line or from PowerShell:

>

Deployment Method:

NOTE

This applies to both open source and commercial editions of Chocolatey.

1. Enter Your Internal Repository Url

(this should look similar to https://community.chocolatey.org/api/v2/)


2. Setup Your Environment

1. Ensure you are set for organizational deployment

Please see the organizational deployment guide

2. Get the package into your environment

  • Open Source or Commercial:
    • Proxy Repository - Create a proxy nuget repository on Nexus, Artifactory Pro, or a proxy Chocolatey repository on ProGet. Point your upstream to https://community.chocolatey.org/api/v2/. Packages cache on first access automatically. Make sure your choco clients are using your proxy repository as a source and NOT the default community repository. See source command for more information.
    • You can also just download the package and push it to a repository Download

3. Copy Your Script

choco upgrade dlss-updater -y --source="'INTERNAL REPO URL'" [other options]

See options you can pass to upgrade.

See best practices for scripting.

Add this to a PowerShell script or use a Batch script with tools and in places where you are calling directly to Chocolatey. If you are integrating, keep in mind enhanced exit codes.

If you do use a PowerShell script, use the following to ensure bad exit codes are shown as failures:


choco upgrade dlss-updater -y --source="'INTERNAL REPO URL'" 
$exitCode = $LASTEXITCODE

Write-Verbose "Exit code was $exitCode"
$validExitCodes = @(0, 1605, 1614, 1641, 3010)
if ($validExitCodes -contains $exitCode) {
  Exit 0
}

Exit $exitCode

- name: Install dlss-updater
  win_chocolatey:
    name: dlss-updater
    version: '2.6.7'
    source: INTERNAL REPO URL
    state: present

See docs at https://docs.ansible.com/ansible/latest/modules/win_chocolatey_module.html.


chocolatey_package 'dlss-updater' do
  action    :install
  source   'INTERNAL REPO URL'
  version  '2.6.7'
end

See docs at https://docs.chef.io/resource_chocolatey_package.html.


cChocoPackageInstaller dlss-updater
{
    Name     = "dlss-updater"
    Version  = "2.6.7"
    Source   = "INTERNAL REPO URL"
}

Requires cChoco DSC Resource. See docs at https://github.com/chocolatey/cChoco.


package { 'dlss-updater':
  ensure   => '2.6.7',
  provider => 'chocolatey',
  source   => 'INTERNAL REPO URL',
}

Requires Puppet Chocolatey Provider module. See docs at https://forge.puppet.com/puppetlabs/chocolatey.


4. If applicable - Chocolatey configuration/installation

See infrastructure management matrix for Chocolatey configuration elements and examples.

Package Approved

This package was approved by moderator Windos on 04 Feb 2025.

Description

DLSS Updater is a utility that automatically updates DLSS (Deep Learning Super Sampling) DLLs for games across multiple platforms including Steam, EA Play, Ubisoft, Epic Games, GOG, and Battle.net. It simplifies the process of keeping your games up-to-date with the latest DLSS improvements.

Note: This application requires administrative privileges to run.

This package does not contain malware, it is a limitation of Pyinstaller with the binary not being signed, please see https://github.com/pyinstaller/pyinstaller/issues/6754#issuecomment-1100821249 for more details.


tools\DLSS_Updater.exe
md5: 0ABCE116881DBFD001077B0EB75107CF | sha1: 6799D8FA4769175E05544D7AF8522FC71DD70C7B | sha256: C45F4B4C33C05B246DDF1E46C8EB14BFECA67BA597C03BA0DD384A7621CA5EDC | sha512: B6E30A0AADD46455CDB8B3B9B6B7E93300930141003CFF63F61517ECF6D58B9295F1B769B6B13853228875DD7192EEB6D95B5CE67F51F6ABA947CD97670A9F22
tools\dlss_updater.png
 
tools\VERIFICATION.TXT
VERIFICATION
Verification is intended to assist the Chocolatey moderators and community
in verifying that this package's contents are trustworthy.

This package is published by the DLSS Updater Project itself. The binaries are 
identical to those published in the GitHub releases section.

Project URL: https://github.com/Recol/DLSS-Updater
Releases: https://github.com/Recol/DLSS-Updater/releases

To verify the binaries:

1. Download the official release from the GitHub releases page
2. Generate a checksum using Get-FileHash in PowerShell
   Get-FileHash DLSS_Updater.exe -Algorithm SHA256
3. Compare the checksum with the one provided in the release notes or in this file

Alternatively, you can use the verification methods provided by GitHub to ensure
the release you're downloading matches the source code at the tagged commit.

Note: This file will be updated with each release to include the specific
checksum for the current version. Always refer to the VERIFICATION.txt
included in the package for the most up-to-date verification information.

Checksum (SHA256) for DLSS_Updater.exe: C45F4B4C33C05B246DDF1E46C8EB14BFECA67BA597C03BA0DD384A7621CA5EDC
tools\_internal\api-ms-win-core-console-l1-1-0.dll
md5: 9F746F4F7D845F063FEA3C37DCEBC27C | sha1: 24D00523770127A5705FCC2A165731723DF36312 | sha256: 88ACE577A9C51061CB7D1A36BABBBEFA48212FADC838FFDE98FDFFF60DE18386 | sha512: 306952418B095E5CF139372A7E684062D05B2209E41D74798A20D7819EFEB41D9A53DC864CB62CC927A98DF45F7365F32B72EC9B17BA1AEE63E2BF4E1D61A6E4
tools\_internal\api-ms-win-core-datetime-l1-1-0.dll
md5: 8F8EB9CB9E78E3A611BC8ACAEC4399CB | sha1: 237EEE6E6E0705C4BE7B0EF716B6A4136BF4E8A8 | sha256: 1BD81DFD19204B44662510D9054852FB77C9F25C1088D647881C9B976CC16818 | sha512: 5B10404CDC29E9FC612A0111B0B22F41D78E9A694631F48F186BDDE940C477C88F202377E887B05D914108B9BE531E6790F8F56E6F03273AB964209D83A60596
tools\_internal\api-ms-win-core-debug-l1-1-0.dll
md5: 226A5983AE2CBBF0C1BDA85D65948ABC | sha1: D0F131DCBA0F0717C5DEA4A9CA7F2E2ECF0AD1C3 | sha256: 591358EB4D1531E9563EE0813E4301C552CE364C912CE684D16576EABF195DC3 | sha512: A1E6671091BD5B2F83BFAA8FCF47093026E354563F84559BD2B57D6E9FA1671EEA27B4ED8493E9FDF4BDE814074DC669DE047B4272B2D14B4F928D25C4BE819D
tools\_internal\api-ms-win-core-errorhandling-l1-1-0.dll
md5: C2F8C03ECCE9941492BFBE4B82F7D2D5 | sha1: 909C66C6DFEA5E0C74D3892D980918251BB08632 | sha256: D56CE7B1CD76108AD6C137326EC694A14C99D48C3D7B0ACE8C3FF4D9BCEE3CE8 | sha512: 7C6C85E390BBE903265574E0E7A074DA2CE30D9376D7A91A121A3E0B1A8B0FFFD5579F404D91836525D4400D2760CB74C9CB448F8C5AE9713385329612B074CF
tools\_internal\api-ms-win-core-fibers-l1-1-0.dll
md5: B5E2760C5A46DBEB8AE18C75F335707E | sha1: E71DB44FC0E0C125DE90A9A87CCB1461E72A9030 | sha256: 91D249D7BC0E38EF6BCB17158B1FDC6DD8888DC086615C9B8B750B87E52A5FB3 | sha512: C3400772D501C5356F873D96B95DC33428A34B6FCAAD83234B6782B5F4BF087121E4FD84885B1ABAB202066DA98EB424F93DD2EED19A0E2A9F6FF4A5CFD1E4F3
tools\_internal\api-ms-win-core-fibers-l1-1-1.dll
md5: 050A30A687E7A2FA6F086A0DB89AA131 | sha1: 1484322CAAF0D71CBB873A2B87BDD8D456DA1A3B | sha256: FC9D86CEC621383EAB636EBC87DDD3F5C19A3CB2A33D97BE112C051D0B275429 | sha512: 07A15AA3B0830F857B9B9FFEB57B6593AE40847A146C5041D38BE9CE3410F58CAA091A7D5671CC1BC7285B51D4547E3004CF0E634AE51FE3DA0051E54D8759E1
tools\_internal\api-ms-win-core-file-l1-1-0.dll
md5: 9F45A47EBFD9D0629F4935764243DD5A | sha1: 86A4A0EA205E31FB73F3BFCCE24945BD6BEA06C7 | sha256: 1CA895ABA4E7435563A6B43E85EBA67A0F8C74AA6A6A94D0FC48FA35535E2585 | sha512: 8C1CDCAD557BFF1685A633D181FCF14EC512D322CAEAEB9C937DA8794C74694FE93528FC9578CB75098F50A2489ED4A5DEDF8C8C2AC93EEB9C8F50E3DD690D5F
tools\_internal\api-ms-win-core-file-l1-2-0.dll
md5: CC228FF8D86B608E73026B1E9960B2F8 | sha1: CEF0705AEE1E8702589524879A49E859505D6FE0 | sha256: 4CADBC0C39DA7C6722206FDCEBD670ABE5B8D261E7B041DD94F9397A89D1990D | sha512: 17ABD9E0EC20B7EB686E3C0F41B043D0742AB7F9501A423B2D2922D44AF660379792D1CC6221EFFBD7E856575D5BABF72657AE9127C87CC5CF678BD2CEB1228F
tools\_internal\api-ms-win-core-file-l2-1-0.dll
md5: E368A236F5676A3DA44E76870CD691C9 | sha1: E4F1D2C6F714A47F0DC29021855C632EF98B0A74 | sha256: 93C624B366BA16C643FC8933070A26F03B073AD0CF7F80173266D67536C61989 | sha512: F5126498A8B65AB20AFAAF6B0F179AB5286810384D44638C35F3779F37E288A51C28BED3C3F8125D51FEB2A0909329F3B21273CB33B3C30728B87318480A9EF8
tools\_internal\api-ms-win-core-handle-l1-1-0.dll
md5: 416AA8314222DB6CBB3760856BE13D46 | sha1: 5F28FE2D565378C033EF8EEA874BC38F4B205327 | sha256: 39095F59C41D76EC81BB2723D646FDE4C148E7CC3402F4980D2ADE95CB9C84F9 | sha512: B16ED31DC3343CAEA47C771326810C040A082E0AB65D9AE69946498CEB6AE0DEE0A570DBCD88090668A100B952C1FF88BADE148811B913C90931AA0E657CD808
tools\_internal\api-ms-win-core-heap-l1-1-0.dll
md5: 344A09B4BE069F86356A89482C156647 | sha1: 2506FFEB157CB531195DD04D11D07C16E4429530 | sha256: 8F105771B236DBCB859DE271F0A6822CE1CB79C36988DD42C9E3F6F55C5F7EB9 | sha512: 4C1E616443576DC83200A4F98D122065926F23212B6647B601470806151FF15EA44996364674821AFEC492B29BA868F188A9D6119B1E1D378A268F1584CA5B29
tools\_internal\api-ms-win-core-interlocked-l1-1-0.dll
md5: 86023497FA48CA2C7705D3F90B76EBC5 | sha1: 835215D7954E57D33D9B34D8850E8DC82F6D09E8 | sha256: 53B25E753CA785BF8B695D89DDE5818A318890211DC992A89146F16658F0B606 | sha512: 8F8370F4C0B27779D18529164FA40CBFDDAFA81A4300D9273713B13428D0367D50583271EA388D43C1A96FED5893448CD14711D5312DA9DFA09B9893DF333186
tools\_internal\api-ms-win-core-kernel32-legacy-l1-1-1.dll
md5: 0C1CC0A54D4B38885E1B250B40A34A84 | sha1: 24400F712BBE1DD260ED407D1EB24C35DCB2ECAC | sha256: A9B13A1CD1B8C19B0C6B4AFCD5BB0DD29C0E2288231AC9E6DB8510094CE68BA6 | sha512: 71674E7ED8650CAC26B6F11A05BFC12BD7332588D21CF81D827C1D22DF5730A13C1E6B3BA797573BB05B3138F8D46091402E63C059650C7E33208D50973DDE39
tools\_internal\api-ms-win-core-libraryloader-l1-1-0.dll
md5: 5FBCB20D99E463259B4F15429010B9CD | sha1: B16770F8BB53DC2BAFCB309824D6FA7B57044D8A | sha256: 7F39BA298B41E4963047341288CAB36B6A241835EE11BA4AD70F44DACD40906C | sha512: 7BA1AC34B3ECFBFB8252F5875BE381D8EF823B50DFE0E070222175EE51191F5EE6D541EEEDD1445ED603A23D200CE9CE15914C8ED3FAFE7E7F3591F51F896C58
tools\_internal\api-ms-win-core-localization-l1-2-0.dll
md5: 5241DF2E95E31E73CCFD6357AD309DF0 | sha1: 2644CC5E86DFAD1AD2140181AB2CA79725F95411 | sha256: 6EE44DD0D8510DC024C9F7C79B1B9FA88C987B26B6BEB6653DDD11751C34E5DC | sha512: 52CCCD1DD237E764E34996C0C5F7A759A7F0EFF29B61BEFEAF96A16D80DF2BA9EE2C3615F875153198A145D68F275AEA6D02187E6EEE5A129E3E2AB81AACEB16
tools\_internal\api-ms-win-core-memory-l1-1-0.dll
md5: 8D285430E8BDA6D5C9B683579ADCB180 | sha1: 619DBBCFF06C659E3FC48F03917A4DADBFC1C275 | sha256: 0512A35316EC9180437F86696A84C5C06A7E4E82E050055A656E5BF9FCA206F9 | sha512: 38405DD85DD62F843ABB55ACEA1B64D7D63BB601445BF1B32078CDE5BBEF4861DD99F26659281FE2AEA86F58CFB1725D8C63D91FB539DCBF5D98CDBE783337FC
tools\_internal\api-ms-win-core-namedpipe-l1-1-0.dll
md5: 4A28CA64F44B91F43945EE3971E0996A | sha1: 45B3D8584C58E8D6AE507FDBD772FEEB1886C8B0 | sha256: C05F1FFFE3B5A2738EA54CE9485CCA026FB9635F982626FBA1E1DCC531897273 | sha512: 862A0428F08D447CD1EE0431969E0FBCB182F4C46418C26D26FA33E586E686D9C093C1CA5781F544CE9276195CE973850719636E39E465F059607F455ECFDD93
tools\_internal\api-ms-win-core-processenvironment-l1-1-0.dll
md5: 7FD4A71085783CCFE9C289C07BCF9B04 | sha1: BB6FFDB5C069DBBA06998DC877D24F72DAD6298D | sha256: C4ECA98C3C67B6395D5B005B00AC1EB0318B86B23AA71035A44C2B1602BEFBA9 | sha512: A96C5B90B8384B239BE111D90CAA3B947651AD73382AB9E5DBE4A4B6AD30921876545331D37C8D5A8F669E39D71BF60983C4BA39C479E23015C2F7579C5E55CD
tools\_internal\api-ms-win-core-processthreads-l1-1-0.dll
md5: C123F2C161884FBFF4F00EF1E1391266 | sha1: 7DB3055DA53916BEA2B85B159491A0772FB620CE | sha256: 5CCB89E93D67BC3288D4E84649C5346E66E15E3D7CD65D989DAF3F4CB584BE9A | sha512: DAC5616320B9052254B5687959E67126C4A938E79173D8245675A9651674384C36CC856F996EF88AE621EC67AFC6616626657585D92BB5D14602A7CC9FC0F669
tools\_internal\api-ms-win-core-processthreads-l1-1-1.dll
md5: 385F562BDC391CCD4F81ACA3719F3236 | sha1: F6633E1DAC227BA3CD14D004748EF0C1C4135E67 | sha256: 4AD565A8BA3EF0EA8AB87221AD11F83EE0BC844CE236607958406663B407333E | sha512: B72ED1A02D4A02791CA5490B35F7E2CB6CB988E4899EDA78134A34FB28964EA573D3289B69D5DB1AAC2289D1F24FD0A432B8187F7AE8147656D38691AE923F27
tools\_internal\api-ms-win-core-profile-l1-1-0.dll
md5: 7A629293EEB0BCA5F9BDEE8ADE477C54 | sha1: A25BF8BAC4FBFD9216EA827E71344BA07B1D463B | sha256: 7809160932F44E59B021699F5BC68799EB7293EE1FA926D6FCCA3C3445302E61 | sha512: 1C58C547D1FE9B54DDF07E5407EDAF3375C6425CA357AA81D09C76A001376C43487476A6F18C891065AB99680501B0F43A16A10ED8E0D5E87B9A9542098F45FE
tools\_internal\api-ms-win-core-rtlsupport-l1-1-0.dll
md5: 3C5C7A3130B075B2DEF5C413C127173F | sha1: F3D2B8AD93F3DC99C8410D34C871AEC56C52E317 | sha256: 9DC1E91E71C7C054854BD1487CB4E6946D82C9F463430F1C4E8D1471005172B1 | sha512: 46A52631E3DD49B0AE10AFBDF50A08D6D6575F3093B3921B2FA744704E2D317F8B10A6D48AD7F922A7843731782521773032A6CC04833B00BD85E404C168FFE4
tools\_internal\api-ms-win-core-string-l1-1-0.dll
md5: 28005B20FBEF6E1DB10912D0FDD6471C | sha1: 47B83697677E08E4EBCFF6FC41ECA7ECE120CC17 | sha256: 60FC31D2A0C634412F529DBA76AF3B9BF991352877C6DAE528186D3935704CFD | sha512: 45D6F860D7F7AEFAA7A0A3B4B21B5C3234F442E39D6259E0A9E2083890533C275F07DDDA93FDDC7445928A55475B83C63253D3B08E41E5576F9029B205DFB36A
tools\_internal\api-ms-win-core-synch-l1-1-0.dll
md5: 436EA0237ED040513EC887046418FAAA | sha1: 44BAFBBDB1B97D86505E16B8A5FCB42B2B771F91 | sha256: 3A72B4F29F39A265D32AD12F0CE15DBF60129C840E10D84D427829EDE45E78AD | sha512: 9F0DBFB538C05383AE9ABFE95E55740530ECC12C1890D8862DEACBC84212BE0740D82AFC9E81D529125221E00B2286CAE0D4B3CA8DD3A6C57774D59F37933692
tools\_internal\api-ms-win-core-synch-l1-2-0.dll
md5: 8F107A7BC018227B181A0E7E76E9CA39 | sha1: EF57E24F29D2B1DEEACEFD82171873B971A3F606 | sha256: EFC1E4460984A73CF47A3DEF033AF1C8F3B1DBC1A56CD27781D3AACF3E3330CB | sha512: D8D8250AAF93FA99E9D1E4286B32579DE0029C83867A787C0A765505A0F8CBD2DD076BB324509D5C4867423BC7DC8F00C8B8458E08E8CBFA8DD731D03DD1AE3F
tools\_internal\api-ms-win-core-sysinfo-l1-1-0.dll
md5: B65BF5EF316880FD8D21E1B34EB5C8A9 | sha1: 3AB4674CB5C76E261FE042D6D0DA8A20BFCBCBAE | sha256: B203D862DDEF1DD62BF623FC866C7F7A9C317C1C2AE30D1F52CB41F955B5698E | sha512: 4AF3B0EF9A813CE1A93A35DD6869817910AE4B628F374477F60EA1831D2CC1AAE7908262672E11954A4953BDFF22BCC5FE23B4A736788E8E5EF4F8AC30EB24F8
tools\_internal\api-ms-win-core-sysinfo-l1-2-0.dll
md5: FC9FC5F308FFC2D2D71814DF8E2AE107 | sha1: 24D7477F2A7DC2610EB701ED683108CD57ECA966 | sha256: 2703635D835396AFD0F138D7C73751AFE7E33A24F4225D08C1690B0A371932C0 | sha512: 490FA6DC846E11C94CFE2F80A781C1BD1943CDDD861D8907DE8F05D9DC7A6364A777C6988C58059E435AC7E5D523218A597B2E9C69C9C34C50D82CAC4400FE01
tools\_internal\api-ms-win-core-timezone-l1-1-0.dll
md5: 43D8D2FB8801C5BD90D9482DDF3EA356 | sha1: D582B55CD58531E726141C63BA9910FF185D72E0 | sha256: 33F4FDDC181066FCE06B2227BDED813F95E94ED1F3D785E982C6B6B56C510C57 | sha512: 0E073381A340DB3F95165DBCCEB8DFBF1ED1B4343E860446032400A7B321B7922C42EE5D9A881E28E69A3F55D56D63663ADB9BB5ABB69C5306EFBF116CC5E456
tools\_internal\api-ms-win-core-util-l1-1-0.dll
md5: 3C58A804B90A0782E80BBBF6C6B6F167 | sha1: B333143E0F6E508B51D27ADF7872B586FA54C794 | sha256: 6EDA016742A6171205A387A14B3C0B331841567740376F56768F8C151724207D | sha512: 773F8DEDED48B34BABE24D955A501F4F357C20125AFFB6EADE36CE6A7ACD380906713C366318F79D627747E636D156875C216FFFAC26DBA25373BBC1C820DA76
tools\_internal\api-ms-win-crt-conio-l1-1-0.dll
md5: 5794B8E183EB547AADD5FAF30A8C4DD2 | sha1: 5B1ED8A9DA14D8ECC4209662809727931AA49307 | sha256: B762061B688AAE679AFE788904D2C9970F74A7DAC98F3B42463D08F25E483D3F | sha512: 3E896854E5DD957AB2B88C82FBAF2EAA03729BAB30FD8518BD999081F4DA9000D9B22894B324E5930DF161C7ADAEC3FC87FD00DE60DCDA34876007AEA4A2FD31
tools\_internal\api-ms-win-crt-convert-l1-1-0.dll
md5: 3560176D0CDBE2F5D33F543348E0A027 | sha1: 1E35A1F7793FC3899927835491F28FE5B903EDCD | sha256: EBB2AE5535A64F65DAEAB8235585114FC9DD2CF1A49F5852D446250B998B6AE4 | sha512: 8AB24C8C9FE8331F21BE96818C5FA69AE5578EB742C4504596310BB0DB7C4C087D350FA47A13ED9FF2E051BB62AC5581DE082D0177923D24FEE6B140AFECF50B
tools\_internal\api-ms-win-crt-environment-l1-1-0.dll
md5: E93C7F013493B12AD40229B19DB02CE6 | sha1: EF878BFBFD2F8328BBB8CFF1AA29A39E624A8503 | sha256: 17D63275D00BDD8670422B95BD264C532998E0A1B041079E54FCE4B6B7A55819 | sha512: 2F4A25EA4062840BEA10442CAD665A72ABBCE747307AD9CE7B3BB89EAF7DCC28F1E9396749576BE304FD793690DDC445653613440442695E72B761EACACB6020
tools\_internal\api-ms-win-crt-filesystem-l1-1-0.dll
md5: 47555752931CECF90E796499B62EC729 | sha1: 217B171764FBA5E91190D1F8A36FECCB3F6D4585 | sha256: 9A9E2A65A281644E368D0F272B95BA5F6B445D1C35910D06056C5EBEB77402DB | sha512: A68009F0306D4D8E70951978D2C184EB80FBEC98C6DB0997BD7B0B503DD63019363CFEF68A9ADBFB568C0A552B774FBDBEB1BCF45F211A6A3224B49E85A5619C
tools\_internal\api-ms-win-crt-heap-l1-1-0.dll
md5: 527BBBFDED529EA77EE798D94CE0F243 | sha1: 647F8C89EB4DB3CF3656292B3DE984B32C6E02A5 | sha256: BAB9AC3EC83E380AE51E4295EF3BF2C738627812D3A49D1E713661ABBC8DC57A | sha512: C1ED69E15AB19084390CF9D1CEAB791758AC4DDD688169F3B814B0E4CF1FC3B6BA17651E35B25DCDC601A8A64821D58933D52A5E939942FA134DFD04FCA04C8B
tools\_internal\api-ms-win-crt-locale-l1-1-0.dll
md5: 09796DAB12CBBD920F632AEB89820193 | sha1: 7D81C0E5537B6D8B79AF0C28CD102E064027C78D | sha256: BD14C67EA28E21D6257AD780A37122C9B5773F69E693F5DB6BFFAEE4D839526E | sha512: 09A6175DCCBBD18A62209E156089F1167DFB8040C97C8C2C14724CE2A8FBE6CE039D7FE04FB8BD60092427BEB7FDD8E7127D611F006FFF1CF2A1AD75E9E5EF3A
tools\_internal\api-ms-win-crt-math-l1-1-0.dll
md5: AA9624CB27CC50A3FBBD3B223A617B1C | sha1: 797AEA1C5CEDD1125276BFC5DCD7A3FB8C6355AA | sha256: 606D66D82DB562EA7979179D06486A0F94D079941D26B80A1E2C49D29959DF6F | sha512: 024975E6787F7A6B0AB6E4B02AD33901F8473B97DC73D4F03B7A116B24AC74150C0C48990EA7A4FB750F9FE728DAFED172796743F802E70F2150EEFCF70FE96A
tools\_internal\api-ms-win-crt-process-l1-1-0.dll
md5: 9D6925407136753E8EB8234D59FA3F1F | sha1: 62631B7007D394FB4D406EA686B291FFF9E486CD | sha256: F6156B1020380EC4F0E48577EBEDAAEF5FB1AB1F337D8B4E72E6A33A7567A9CC | sha512: AB04DE62524E465810CD0EE81E85018863E276D49861E67A920667AF802E94869B816B47A6E3C4738179A7A7D726D44BBBA6E47D9097363A63EAFF51CD56DE8A
tools\_internal\api-ms-win-crt-runtime-l1-1-0.dll
md5: BBAA58E9E1ABDF7D8C4C69652D29D789 | sha1: 38AEF13ABC14502354E8C5C3C37B97A8E2E5FDCF | sha256: C5902934D026D7E15FBE9917D474F3322846A41A25E66F4B2B1F758801879F4B | sha512: 7882A8E1E1EA7E217F70FF9DF27D36709B4BE23588909EF002F3EB1B9A7D3EEA2591A8524AF2C83448DDFFF0911658517C6989683245C54678583F359A78B0AD
tools\_internal\api-ms-win-crt-stdio-l1-1-0.dll
md5: EF37235FC43157A4C93241D5E49E304B | sha1: D4DE26B36812C2DDCCD1618B4D7AC02AD1B42273 | sha256: A9C5A153D8C0286F9B41A2B1C65854AD9E6471B8755B7DE87BAE4470E60BCAB6 | sha512: C0857760D5D069BEEB1EB1737F4160530910331BF6047022836CF58137BD28C2A966A8760A681859F57EBD810FD424CE231402EDDDE1316EAEF7B6F9F773AFBB
tools\_internal\api-ms-win-crt-string-l1-1-0.dll
md5: 639B1FB35CB61BA633EB1791B750631F | sha1: 392A6925009F5FB02A4C122C9CE31D82B9059628 | sha256: 25B8F83A7767211B11132775A0E27A45AA4EC8AB4E6572599F9C172AE3606B40 | sha512: DEF547EF66673862CEA9BB13C433EDCE24A3075C328D9B3B9452F2F01F2F4243DAAB38C0F8571C52D601BC4AECAAA0682DBEBF6BE41CAE345787A719063EBF58
tools\_internal\api-ms-win-crt-time-l1-1-0.dll
md5: FCCCE207A34C947F01D3F23A7DD09569 | sha1: 75F722801C77285DB98A08AF763252A0255E99E2 | sha256: 7C7F6393F06DE11750ADB09CC5698AE55CD9FB27B2E51E207286FEB1B5B2B156 | sha512: D3D923F133594EB4325F4A6E5ED46FCC348A7C0F310F14EAA38C6FAD070BA637BDB4A77200FEB231114E111D07A86595A6130291028CDE3A284D9F847EC38AD4
tools\_internal\api-ms-win-crt-utility-l1-1-0.dll
md5: 708A5BC205384633A7B6674EECC7F0F0 | sha1: 01603A7826029293236C67FCE02ACE8D392A0514 | sha256: D8BA5F17B9FFCBF3AEAF3FA1DA226832D2FA90F81ACCE0CD669464E76CE434AC | sha512: 8638845326AB6543338BAA7A644AF8BE33A123E1FC9DA2037158BE7C8D165691CCD06CB3FF73696A30B8801EAB030E81F93DB81216BB3B7E83A320A0DF5AF270
tools\_internal\base_library.zip
md5: 18C3F8BF07B4764D340DF1D612D28FAD | sha1: FC0E09078527C13597C37DBEA39551F72BBE9AE8 | sha256: 6E30043DFA5FAF9C31BD8FB71778E8E0701275B620696D29AD274846676B7175 | sha512: 135B97CD0284424A269C964ED95B06D338814E5E7B2271B065E5EABF56A8AF4A213D863DD2A1E93C1425FADB1B20E6C63FFA6E8984156928BE4A9A2FBBFD5E93
tools\_internal\dlss_updater\auto_updater.py
import os
import sys
import json
import shutil
import zipfile
import subprocess
import time
from urllib import request
from urllib.error import URLError
from packaging import version
from dlss_updater.version import __version__
from dlss_updater.logger import setup_logger

logger = setup_logger()

GITHUB_API_URL = "https://api.github.com/repos/Recol/DLSS-Updater/releases/latest"


def check_for_updates():
    """
    Check for available updates by comparing versions.
    Returns (latest_version, download_url) tuple or (None, None) if no update available.
    """
    try:
        with request.urlopen(GITHUB_API_URL) as response:
            latest_release = json.loads(response.read().decode())
        latest_version = latest_release["tag_name"].lstrip("V")

        if version.parse(latest_version) > version.parse(__version__):
            return latest_version, latest_release["assets"][0]["browser_download_url"]
        else:
            return None, None
    except URLError as e:
        logger.error(f"Error checking for updates: {e}")
        return None, None


def download_update(download_url):
    """
    Download and extract the update package.
    Returns path to new executable or None if download/extraction fails.
    """
    try:
        update_dir = os.path.join(os.path.dirname(sys.executable), "update")
        os.makedirs(update_dir, exist_ok=True)
        update_zip = os.path.join(update_dir, "update.zip")

        logger.info("Downloading update package...")
        request.urlretrieve(download_url, update_zip)

        logger.info("Extracting update package...")
        with zipfile.ZipFile(update_zip, "r") as zip_ref:
            zip_ref.extractall(update_dir)

        os.remove(update_zip)

        # Look for the new executable
        new_exe = None
        for root, dirs, files in os.walk(update_dir):
            for file in files:
                if file.lower() == "dlss_updater.exe":
                    new_exe = os.path.join(root, file)
                    break
            if new_exe:
                break

        if new_exe:
            logger.info(f"Found new executable: {new_exe}")
            return new_exe
        else:
            logger.error("Error: New executable not found in the update package.")
            return None
    except Exception as e:
        logger.error(f"Error downloading update: {e}")
        if os.path.exists(update_dir):
            shutil.rmtree(update_dir)
        return None


def update_script(current_exe, new_exe):
    """
    Perform the actual update by replacing the old executable with the new one.
    """
    # Wait for the original process to exit
    time.sleep(2)

    try:
        # Replace the old executable with the new one
        os.remove(current_exe)
        shutil.move(new_exe, current_exe)

        # Clean up the update directory
        update_dir = os.path.dirname(new_exe)
        shutil.rmtree(update_dir)

        # Start the updated executable
        subprocess.Popen([current_exe], creationflags=subprocess.CREATE_NEW_CONSOLE)

        # Log the update completion
        with open(
            os.path.join(os.path.dirname(current_exe), "update_log.txt"), "w"
        ) as f:
            f.write(f"Update completed at {time.ctime()}. New executable started.")

    except Exception as e:
        # Log the error
        with open(
            os.path.join(os.path.dirname(current_exe), "update_error_log.txt"), "w"
        ) as f:
            f.write(f"Error during update process at {time.ctime()}: {str(e)}")


def perform_update(new_exe_path):
    """
    Start the update process in a new process and exit the current one.
    """
    current_exe = sys.executable

    # Start the update process in a separate process
    subprocess.Popen(
        [sys.executable, __file__, "update", current_exe, new_exe_path],
        creationflags=subprocess.CREATE_NO_WINDOW,
    )

    # Exit the current process
    sys.exit(0)


def auto_update():
    """
    Main update function that orchestrates the update process.
    Returns True if an update was downloaded and ready to install,
    False otherwise.
    """
    logger.info("Checking for updates...")
    latest_version, download_url = check_for_updates()

    if latest_version:
        logger.info(f"New version available: {latest_version}")
        new_exe_path = download_update(download_url)

        if new_exe_path:
            logger.info("Update downloaded successfully.")
            logger.info(
                "The application will now close and update. It will restart automatically."
            )
            perform_update(new_exe_path)
            return True
    else:
        logger.info("No updates available. You have the latest version.")

    return False


if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "update":
        update_script(sys.argv[2], sys.argv[3])
tools\_internal\dlss_updater\config.py
import os
import sys
import configparser
from enum import StrEnum
import appdirs
from .logger import setup_logger

logger = setup_logger()


def get_config_path():
    """Get the path for storing configuration files"""
    app_name = "DLSS-Updater"
    app_author = "Recol"
    config_dir = appdirs.user_config_dir(app_name, app_author)
    os.makedirs(config_dir, exist_ok=True)
    return os.path.join(config_dir, "config.ini")


def resource_path(relative_path):
    """Get absolute path to resource, works for dev and for PyInstaller"""
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)


LATEST_DLL_VERSIONS = {
    "nvngx_dlss.dll": "310.2.1.0",
    "nvngx_dlssg.dll": "310.2.0.0",
    "nvngx_dlssd.dll": "310.2.0.0",
}

LATEST_DLL_PATHS = {
    "nvngx_dlss.dll": resource_path(os.path.join("latest_dll", "nvngx_dlss.dll")),
    "nvngx_dlssg.dll": resource_path(os.path.join("latest_dll", "nvngx_dlssg.dll")),
    "nvngx_dlssd.dll": resource_path(os.path.join("latest_dll", "nvngx_dlssd.dll")),
}


class LauncherPathName(StrEnum):
    STEAM = "SteamPath"
    EA = "EAPath"
    EPIC = "EpicPath"
    GOG = "GOGPath"
    UBISOFT = "UbisoftPath"
    BATTLENET = "BattleDotNetPath"
    XBOX = "XboxPath"


class ConfigManager(configparser.ConfigParser):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(ConfigManager, cls).__new__(cls)
        return cls._instance

    def __init__(self):
        if not hasattr(self, "initialized"):
            super().__init__()
            self.logger = setup_logger()
            self.config_path = get_config_path()
            self.read(self.config_path)
            
            # Initialize sections
            sections = {
                "LauncherPaths": {
                    LauncherPathName.STEAM: "",
                    LauncherPathName.EA: "",
                    LauncherPathName.EPIC: "",
                    LauncherPathName.GOG: "",
                    LauncherPathName.UBISOFT: "",
                    LauncherPathName.BATTLENET: "",
                    LauncherPathName.XBOX: "",
                },
                "Settings": {
                    "CheckForUpdatesOnStart": "True",
                    "AutoBackup": "True",
                    "MinimizeToTray": "False",
                },
                "Updates": {
                    "LastUpdateCheck": "",
                    "CurrentDLSSVersion": LATEST_DLL_VERSIONS["nvngx_dlss.dll"],
                }
            }
            
            for section, values in sections.items():
                if not self.has_section(section):
                    self.add_section(section)
                for key, value in values.items():
                    if key not in self[section]:
                        self[section][key] = value
            
            self.save()
            self.initialized = True

    def update_launcher_path(self, path_to_update: LauncherPathName, new_launcher_path: str):
        """Update launcher path in config"""
        self.logger.debug(f"Attempting to update path for {path_to_update}.")
        self["LauncherPaths"][path_to_update] = new_launcher_path
        self.save()
        self.logger.debug(f"Updated path for {path_to_update}.")

    def check_path_value(self, path_to_check: LauncherPathName) -> str:
        """Get launcher path from config"""
        return self["LauncherPaths"].get(path_to_check, "")

    def reset_launcher_path(self, path_to_reset: LauncherPathName):
        """Reset launcher path to default empty value"""
        self.logger.debug(f"Resetting path for {path_to_reset}")
        self["LauncherPaths"][path_to_reset] = ""
        self.save()

    def get_setting(self, setting_name: str, default_value: str = "") -> str:
        """Get setting value with fallback"""
        return self["Settings"].get(setting_name, default_value)

    def update_setting(self, setting_name: str, value: str):
        """Update setting value"""
        self["Settings"][setting_name] = value
        self.save()

    def update_last_check_time(self, timestamp: str):
        """Update last update check timestamp"""
        self["Updates"]["LastUpdateCheck"] = timestamp
        self.save()

    def update_current_dlss_version(self, version: str):
        """Update current DLSS version"""
        self["Updates"]["CurrentDLSSVersion"] = version
        self.save()

    def save(self):
        """Save configuration to disk"""
        with open(self.config_path, "w") as configfile:
            self.write(configfile)


config_manager = ConfigManager()
tools\_internal\dlss_updater\constants.py
DLL_TYPE_MAP = {
    "nvngx_dlss.dll": "DLSS DLL",
    "nvngx_dlssg.dll": "DLSS Frame Generation DLL",
    "nvngx_dlssd.dll": "DLSS Ray Reconstruction DLL",
}
tools\_internal\dlss_updater\dlss_updater.log
 
tools\_internal\dlss_updater\icons\battlenet.png
 
tools\_internal\dlss_updater\icons\dlss_updater.ico
 
tools\_internal\dlss_updater\icons\dlss_updater.png
 
tools\_internal\dlss_updater\icons\dlss_updater_full.png
 
tools\_internal\dlss_updater\icons\ea.png
 
tools\_internal\dlss_updater\icons\epic.png
 
tools\_internal\dlss_updater\icons\gog.png
 
tools\_internal\dlss_updater\icons\reset.png
 
tools\_internal\dlss_updater\icons\steam.png
 
tools\_internal\dlss_updater\icons\ubisoft.png
 
tools\_internal\dlss_updater\icons\update.png
 
tools\_internal\dlss_updater\icons\xbox.png
 
tools\_internal\dlss_updater\lib\threading_lib.py
from PyQt6.QtCore import QThreadPool, QRunnable, pyqtSignal, QObject

class WorkerSignals(QObject):
    """Signals available from a running worker thread."""
    finished = pyqtSignal()
    result = pyqtSignal(object)
    error = pyqtSignal(tuple)
    progress = pyqtSignal(int)


class Worker(QRunnable):
    """
    Worker thread for running background tasks.
    
    Inherits from QRunnable for better thread pool management.
    """
    def __init__(self, fn, *args, **kwargs):
        super().__init__()
        
        # Store constructor arguments (re-used for processing)
        self.fn = fn
        self.args = args
        self.kwargs = kwargs
        
        # Create signals for communication
        self.signals = WorkerSignals()
        
        # Add an option to stop the worker if needed
        self.is_running = True

    def run(self):
        """
        Initialise the runner function with passed args, kwargs.
        
        Automatic handling of different function signatures and return values.
        """
        try:
            # Retrieve args/kwargs here; and fire processing using them
            result = self.fn(*self.args, **self.kwargs)
        except Exception as e:
            # If function raised an exception, capture it
            import traceback
            
            # Package the exception details
            exctype = type(e)
            value = str(e)
            tb = traceback.format_exc()
            
            # If still running, emit the error signal
            if self.is_running:
                self.signals.error.emit((exctype, value, tb))
        else:
            # If function successfully completed, emit result
            if self.is_running:
                if result is not None:
                    self.signals.result.emit(result)
        finally:
            # Always emit finished signal
            if self.is_running:
                self.signals.finished.emit()

    def stop(self):
        """Set the running state to False to prevent further signal emissions."""
        self.is_running = False


class ThreadManager:
    """
    Manages thread pool and worker creation for background tasks.
    
    Provides a simplified interface for running functions in a thread pool.
    """
    def __init__(self, parent=None):
        # Create a thread pool
        self.thread_pool = QThreadPool()
        
        # Set up maximum thread count (adjust as needed)
        self.thread_pool.setMaxThreadCount(1)
        
        # Store the current worker
        self.current_worker = None
        
        # Store the parent (optional)
        self.parent = parent
        
        # Signals to be connected from the current worker
        self.signals = None

    def assign_function(self, func, *args, **kwargs):
        """
        Assign a function to be run in a background thread.
        
        Stops any existing worker before creating a new one.
        """
        # Stop any existing worker
        if self.current_worker:
            self.current_worker.stop()
        
        # Create a new worker
        worker = Worker(func, *args, **kwargs)
        
        # Store the current worker
        self.current_worker = worker
        
        # Update signals reference
        self.signals = worker.signals

    def run(self):
        """
        Run the currently assigned worker in the thread pool.
        
        Adds the worker to the thread pool for execution.
        """
        if self.current_worker:
            # Add worker to thread pool
            self.thread_pool.start(self.current_worker)

    def waitForDone(self):
        """
        Wait for all threads in the pool to complete.
        
        Useful for clean shutdown of the application.
        """
        # Stop current worker if exists
        if self.current_worker:
            self.current_worker.stop()
        
        # Wait for thread pool to finish
        self.thread_pool.waitForDone()
tools\_internal\dlss_updater\logger.py
import logging
import sys
from pathlib import Path
from PyQt6.QtCore import QObject, pyqtSignal, Qt
from PyQt6.QtWidgets import QTextBrowser


class QLoggerLevelSignal(QObject):
    """Signals for the Logger QTextBrowser derived class."""
    debug = pyqtSignal()
    info = pyqtSignal()
    warning = pyqtSignal()
    error = pyqtSignal()


class LoggerWindow(QTextBrowser):
    """A QTextBrowser subclass that have signals and a dict for ease of access to said signals."""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.signals = QLoggerLevelSignal()
        self.signals_to_emit = {
            "DEBUG": self.signals.debug,
            "INFO": self.signals.info,
            "WARNING": self.signals.warning,
            "ERROR": self.signals.error,
        }
        # Set document max size to prevent memory issues with very large logs
        self.document().setMaximumBlockCount(5000)  # Limit to last 5000 lines
        # Set text browser properties
        self.setReadOnly(True)
        self.setOpenExternalLinks(False)
        # Enable smooth scrolling
        self.verticalScrollBar().setSingleStep(2)


class QLogger(logging.Handler, QObject):
    """Logger handler for the Qt GUI"""
    # Define the signal as a class attribute
    logMessage = pyqtSignal(str, str)

    def __init__(self, text_browser):
        logging.Handler.__init__(self)
        QObject.__init__(self)  # Initialize QObject
        
        self.text_browser = text_browser
        self.colors_dict = {
            "DEBUG": "white",
            "INFO": "green", 
            "WARNING": "yellow",
            "ERROR": "red",
        }
        # Connect the signal to the slot method
        self.logMessage.connect(self.write_log, Qt.ConnectionType.QueuedConnection)

    def emit(self, record):
        """
        Logs the record to the text browser object.
        @param record: LogRecord object to log.
        """
        msg = self.format(record)
        # Emit the signal with levelname and formatted message
        self.logMessage.emit(record.levelname, msg)

    def write_log(self, levelname, msg):
        """Write the log message to the text browser in the main thread."""
        color = self.colors_dict[levelname]
        formatted_msg = f'<font color="{color}">{msg}</font>'
        self.text_browser.signals_to_emit[levelname].emit()
        self.text_browser.append(formatted_msg)
        # Scroll to bottom
        scrollbar = self.text_browser.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())


def setup_logger(log_file_name="dlss_updater.log"):
    """
    Setups the initial logger.
    param: log_file_name: filename to be used for the logfile.
    return: logger instance created.
    """
    logger = logging.getLogger("DLSSUpdater")

    # Check if the logger has already been configured
    if not logger.handlers:
        logger.setLevel(logging.DEBUG)

        log_file_path = (
            Path(sys.executable).parent / log_file_name
            if getattr(sys, "frozen", False)
            else Path(__file__).parent / log_file_name
        )

        # Create handlers
        console_handler = logging.StreamHandler(sys.stdout)
        file_handler = logging.FileHandler(log_file_path, encoding="utf-8")

        # Create formatter and add it to handlers
        log_format = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
        console_handler.setFormatter(log_format)
        file_handler.setFormatter(log_format)

        # Add handlers to the logger
        logger.addHandler(console_handler)
        logger.addHandler(file_handler)

        # Prevent propagation to avoid duplicate logs
        logger.propagate = False

    return logger


def add_qt_handler(logger_to_extend, text_browser):
    """
    Add a QTextBrowser handler to an existing logger instance.
    @param: logger_to_extend: logger instance to be extended.
    @param: text_browser: QTextBrowser instance to be added as a logger.
    """
    # Remove any existing QLogger handlers
    for handler in logger_to_extend.handlers[:]:
        if isinstance(handler, QLogger):
            logger_to_extend.removeHandler(handler)

    # Create a new QLogger handler
    text_browser_handler = QLogger(text_browser)
    formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
    text_browser_handler.setFormatter(formatter)
    logger_to_extend.addHandler(text_browser_handler)


# Usage example
if __name__ == "__main__":
    logger = setup_logger()
    logger.info("This is a test log message")
    logger.info("This is a test logger.info message with an argument: %s", "test arg")
tools\_internal\dlss_updater\main_ui\main_window.py
from .. import __version__, resource_path
from ..utils import update_dlss_versions
import os
from PyQt6.QtCore import Qt, QUrl, QSize
from PyQt6.QtGui import QDesktopServices, QIcon, QPixmap
from dlss_updater.lib.threading_lib import ThreadManager
from pathlib import Path
from dlss_updater.config import config_manager, LauncherPathName
from dlss_updater.logger import add_qt_handler, LoggerWindow, setup_logger
from PyQt6.QtWidgets import (
    QMainWindow,
    QWidget,
    QVBoxLayout,
    QSplitter,
    QPushButton,
    QFileDialog,
    QHBoxLayout,
    QLabel,
    QMenu,
    QDialog,
    QTextBrowser,
    QMessageBox,
)
from dlss_updater.utils import extract_game_name, DLL_TYPE_MAP


class MainWindow(QMainWindow):
    def __init__(self, logger=None):
        super().__init__()
        self.thread_manager = ThreadManager(self)
        self.button_enum_dict = {}
        self.setWindowTitle("DLSS-Updater")
        self.setGeometry(100, 100, 600, 350)
        self.logger_expanded = False
        self.original_width = None

        # Load and set the window icon
        logo_path = resource_path(os.path.join("icons", "dlss_updater.png"))
        logo_icon = QIcon(logo_path)
        self.setWindowIcon(logo_icon)

        # Main container
        main_container = QWidget()
        main_layout = QVBoxLayout()
        header_layout = QHBoxLayout()

        main_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
        # Header section with welcome, logo, version, and other buttons
        header_left = QHBoxLayout()
        welcome_label = QLabel("Welcome to the GUI :) -Deco")
        version_label = QLabel(f"v{__version__}")
        welcome_label.setStyleSheet("color: white; font-size: 16px;")
        version_label.setStyleSheet(
            "color: #888888; font-size: 12px; margin-left: 8px;"
        )
        header_left.addWidget(welcome_label)
        header_left.addStretch()
        header_left.addWidget(version_label)

        # Add the header layout to the main layout
        header_layout.addLayout(header_left)
        main_layout.addLayout(header_layout)

        # Add the DLSS Updater logo as a separate element
        self.logo_label = QLabel()
        self.logo_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        main_layout.addWidget(self.logo_label)

        # Custom folders info
        info_label = QLabel(
            "Note: For custom game folders, use any launcher button (e.g. Battle.net) and select your folder location."
        )
        info_label.setWordWrap(True)
        info_label.setStyleSheet(
            "color: white; background-color: #3C3C3C; padding: 10px; border-radius: 4px;"
        )
        main_layout.addWidget(info_label)

        # Donate, report a bug, contact, release notes, and view logs buttons
        button_layout = QHBoxLayout()
        donate_button = QPushButton("☕ Support Development")
        donate_button.clicked.connect(
            lambda: QDesktopServices.openUrl(QUrl("https://buymeacoffee.com/decouk"))
        )
        report_bug_button = QPushButton("🐛 Report a Bug")
        report_bug_button.clicked.connect(
            lambda: QDesktopServices.openUrl(
                QUrl("https://github.com/Recol/DLSS-Updater/issues")
            )
        )
        contact_button = QPushButton("📞 Contact")
        contact_menu = QMenu()
        twitter_action = contact_menu.addAction("Twitter")
        discord_action = contact_menu.addAction("Discord")
        twitter_action.triggered.connect(
            lambda: QDesktopServices.openUrl(QUrl("https://x.com/iDeco_UK"))
        )
        discord_action.triggered.connect(
            lambda: QDesktopServices.openUrl(
                QUrl("https://discord.com/users/162568099839606784")
            )
        )
        contact_button.setMenu(contact_menu)
        release_notes_button = QPushButton("📝 Release Notes")
        release_notes_button.clicked.connect(self.show_release_notes)
        view_logs_button = QPushButton("📋 View Logs")
        view_logs_button.clicked.connect(self.toggle_logger_window)
        button_layout.addWidget(donate_button)
        button_layout.addWidget(report_bug_button)
        button_layout.addWidget(contact_button)
        button_layout.addWidget(release_notes_button)
        button_layout.addWidget(view_logs_button)
        main_layout.addLayout(button_layout)

        # Original logger splitter setup
        self.logger_splitter = QSplitter(Qt.Orientation.Horizontal)
        self.can_continue = False
        self.button_list = []
        self.path_list = []

        # Launcher buttons setup
        self.setup_launcher_buttons()

        # Create QTextBrowser widget
        self.logger_window = LoggerWindow(self)

        # Set up splitter layout
        self.logger_splitter.addWidget(self.browse_buttons_container_widget)
        self.logger_splitter.addWidget(self.logger_window)
        # We want the logger_window to be collapsed by default
        self.logger_splitter.setSizes([1, 0])

        main_layout.addWidget(self.logger_splitter)
        main_container.setLayout(main_layout)
        self.setCentralWidget(main_container)

        # Set up logging
        self.logger = logger or setup_logger()
        add_qt_handler(self.logger, self.logger_window)
        self.logger_window.signals.error.connect(self.expand_logger_window)

        # Connect the update button to the threaded update function
        self.start_update_button.clicked.connect(self.call_threaded_update)

        self.apply_dark_theme()

    def show_release_notes(self):
        """Display release notes in a dialog"""
        release_notes_file = Path(resource_path("release_notes.txt"))
        if release_notes_file.exists():
            with open(release_notes_file, "r") as file:
                notes = file.read()
                dialog = QDialog(self)
                dialog.setWindowTitle("Release Notes")
                layout = QVBoxLayout()
                text_browser = QTextBrowser()
                text_browser.setPlainText(notes)
                text_browser.setStyleSheet("background-color: #3C3C3C; color: white;")
                layout.addWidget(text_browser)
                dialog.setLayout(layout)
                dialog.resize(500, 400)
                dialog.exec()

    def reset_path(self):
        """Reset the associated launcher path"""
        reset_button = self.sender()
        launcher_button = reset_button.property("reset_button")
        if launcher_button:
            launcher_enum = self.button_enum_dict.get(launcher_button.objectName())
            if launcher_enum:
                config_manager.reset_launcher_path(launcher_enum)
                launcher_button.setText(launcher_button.objectName())
                self.logger.info(f"Reset path for {launcher_button.objectName()}")

    def expand_logger_window(self):
        """Increase app window size and expands the logger window. Used only for errors."""
        if self.logger_expanded:
            return
        self.original_width = self.width()
        self.setFixedWidth(int(self.width() * 1.4))
        self.logger_splitter.setSizes([int(self.width()), int(self.width())])
        self.logger_expanded = True

    def toggle_logger_window(self):
        """Increase app window size and expands the logger window."""
        try:
            if self.logger_expanded:
                self.logger_splitter.setSizes([1, 0])
                self.setFixedWidth(self.original_width)
                self.logger_expanded = False
                return

            # Store original width before expanding
            self.original_width = self.width()

            # Expand window
            self.setFixedWidth(int(self.width() * 1.4))
            self.logger_splitter.setSizes([int(self.width()), int(self.width())])
            self.logger_expanded = True

        except Exception as e:
            self.logger.error(f"Error toggling logger window: {e}")

    def create_styled_button(
        self, text: str, icon_path: str, tooltip: str = ""
    ) -> QPushButton:
        """
        Creates styled buttons with the specific icon and tooltip.
        @param text: Text to be displayed.
        @param icon_path: Path to the icon.
        @param tooltip: Tooltip on hover. Optional.
        @return: QPushButton Created button.
        """
        button = QPushButton(f"  {text}", self)

        # Load and process icon
        icon = QIcon(resource_path(os.path.join("icons", icon_path)))
        button.setIcon(icon)
        button.setIconSize(QSize(24, 24))  # Consistent icon size

        # Set fixed height for uniformity
        button.setMinimumHeight(40)

        if tooltip:
            button.setToolTip(tooltip)

        # Connect to browse functionality if not the update button
        if "Update" not in text:
            button.clicked.connect(self.browse_folder)

        return button

    def setup_launcher_buttons(self):
        """Setups the launcher buttons."""
        # Create launcher buttons
        self.steam_text_browser = self.create_styled_button(
            "Steam Games", "steam.png", "Select Steam game locations"
        )
        self.ea_text_browser = self.create_styled_button(
            "EA Games", "ea.png", "Select EA game locations"
        )
        self.ubisoft_text_browser = self.create_styled_button(
            "Ubisoft Games", "ubisoft.png", "Select Ubisoft game locations"
        )
        self.epic_text_browser = self.create_styled_button(
            "Epic Games", "epic.png", "Select Epic game locations"
        )
        self.gog_text_browser = self.create_styled_button(
            "GOG Games", "gog.png", "Select GOG game locations"
        )
        self.battlenet_text_browser = self.create_styled_button(
            "Battle.net Games", "battlenet.png", "Select Battle.net game locations"
        )
        self.xbox_text_browser = self.create_styled_button(
            "Xbox Games", "xbox.png", "Select Xbox game locations"
        )

        # Update button with special styling
        self.start_update_button = self.create_styled_button(
            "Start Update", "update.png", "Start DLSS update process"
        )

        # Set object names for identification
        self.steam_text_browser.setObjectName("Steam")
        self.ea_text_browser.setObjectName("EA")
        self.ubisoft_text_browser.setObjectName("UBISOFT")
        self.epic_text_browser.setObjectName("EPIC")
        self.gog_text_browser.setObjectName("GOG")
        self.battlenet_text_browser.setObjectName("BATTLENET")
        self.xbox_text_browser.setObjectName("XBOX")

        # Store buttons in list
        self.button_list = [
            self.steam_text_browser,
            self.ea_text_browser,
            self.ubisoft_text_browser,
            self.epic_text_browser,
            self.gog_text_browser,
            self.battlenet_text_browser,
            self.xbox_text_browser,
        ]

        # Update button dictionary
        self.button_enum_dict.update(
            {
                "Steam": LauncherPathName.STEAM,
                "EA": LauncherPathName.EA,
                "UBISOFT": LauncherPathName.UBISOFT,
                "EPIC": LauncherPathName.EPIC,
                "GOG": LauncherPathName.GOG,
                "BATTLENET": LauncherPathName.BATTLENET,
                "XBOX": LauncherPathName.XBOX,
            }
        )

        # Create layout for buttons with reset buttons
        browse_buttons_layout = QVBoxLayout()
        for button in self.button_list:
            button_row = QHBoxLayout()
            button_row.addWidget(button, stretch=1)

            # Create reset button
            reset_button = QPushButton()
            reset_button.setIcon(
                QIcon(resource_path(os.path.join("icons", "reset.png")))
            )
            reset_button.setIconSize(QSize(16, 16))
            reset_button.setFixedSize(24, 24)
            reset_button.setToolTip("Reset path")
            reset_button.setProperty("reset_button", button)
            reset_button.clicked.connect(self.reset_path)
            reset_button.setStyleSheet(
                """
                QPushButton {
                    background-color: #4D4D4D;
                    border: 1px solid #7F7F7F;
                    border-radius: 4px;
                    padding: 2px;
                    margin: 2px;
                }
                QPushButton:hover {
                    background-color: #5A5A5A;
                }
                QPushButton:pressed {
                    background-color: #444444;
                }
            """
            )

            button_row.addWidget(reset_button)
            browse_buttons_layout.addLayout(button_row)

        browse_buttons_layout.addWidget(self.start_update_button)
        self.browse_buttons_container_widget = QWidget()
        self.browse_buttons_container_widget.setLayout(browse_buttons_layout)

    def call_threaded_update(self):
        """Start the update process in a separate thread."""
        try:
            # Disable the button immediately to prevent multiple clicks
            self.start_update_button.setEnabled(False)
            self.logger.info("Starting update process in thread...")

            # Clear any previous signal connections
            if self.thread_manager.signals:
                try:
                    # Disconnect previous connections if they exist
                    self.thread_manager.signals.finished.disconnect()
                    self.thread_manager.signals.result.disconnect()
                    self.thread_manager.signals.error.disconnect()
                except TypeError:
                    # Ignore errors if signals were not connected
                    pass

            # Assign the update function
            self.thread_manager.assign_function(update_dlss_versions)

            # Connect new signals
            self.thread_manager.signals.finished.connect(self.handle_update_finished)
            self.thread_manager.signals.result.connect(self.handle_update_result)
            self.thread_manager.signals.error.connect(self.handle_update_error)

            # Run the thread
            self.thread_manager.run()

        except Exception as e:
            self.logger.error(f"Error starting update thread: {e}")
            import traceback

            self.logger.error(traceback.format_exc())
            # Ensure button is re-enabled in case of an error
            self.start_update_button.setEnabled(True)

    def handle_update_error(self, error):
        """
        Handle errors from the update thread.
        @param error: The error from the update thread.
        """
        exctype, value, tb = error
        self.logger.error(f"Error: {exctype}")
        self.logger.error(f"Value: {value}")
        self.logger.error(f"Traceback: {tb}")
        self.start_update_button.setEnabled(True)

    def handle_update_result(self, result):
        """
        Handle results from the update thread.
        @param result: Tuple containing (success, updated_games, skipped_games, successful_backups)
        """
        try:
            if isinstance(result, tuple) and len(result) == 4:
                success, updated_games, skipped_games, successful_backups = result
                if success:
                    self.logger.info("Update process completed successfully")
                    self.show_update_summary(
                        (updated_games, skipped_games, successful_backups)
                    )
                else:
                    self.logger.error("Update process failed")
            else:
                self.logger.error(f"Unexpected result format: {result}")
        except Exception as e:
            self.logger.error(f"Error handling update result: {e}")
            import traceback

            self.logger.error(traceback.format_exc())
        finally:
            self.start_update_button.setEnabled(True)

    def handle_update_finished(self):
        """Handle completion of the update thread."""
        try:
            self.logger.debug("Update thread finished")
            self.start_update_button.setEnabled(True)
            # Clean up worker reference
            self._current_worker = None
        except Exception as e:
            self.logger.error(f"Error in update finished handler: {e}")

    def closeEvent(self, event):
        """Handle application close event."""
        try:
            if self.thread_manager and self.thread_manager.current_worker:
                self.thread_manager.waitForDone()
        except Exception as e:
            self.logger.error(f"Error during cleanup: {e}")
        super().closeEvent(event)

    def get_current_settings(self):
        """Get the current settings from the settings file."""
        steam_path = config_manager.check_path_value(LauncherPathName.STEAM)
        ea_path = config_manager.check_path_value(LauncherPathName.EA)
        ubisoft_path = config_manager.check_path_value(LauncherPathName.UBISOFT)
        epic_path = config_manager.check_path_value(LauncherPathName.EPIC)
        gog_path = config_manager.check_path_value(LauncherPathName.GOG)
        battlenet_path = config_manager.check_path_value(LauncherPathName.BATTLENET)
        xbox_path = config_manager.check_path_value(LauncherPathName.XBOX)

        self.path_list = [
            steam_path,
            ea_path,
            ubisoft_path,
            epic_path,
            gog_path,
            battlenet_path,
            xbox_path,
        ]

        for i, button in enumerate(self.button_list):
            if self.path_list[i]:
                button.setText(self.path_list[i])

    def browse_folder(self):
        """Open a dialog to select a directory."""
        directory = QFileDialog.getExistingDirectory(self, "Select Folder")
        if directory:
            directory = directory.replace("/", "\\")
            self.sender().setText(directory)
            config_manager.update_launcher_path(
                self.button_enum_dict.get(self.sender().objectName()), directory
            )

    def show_update_summary(self, update_result):
        """Display the update summary in a message box."""
        updated_games, skipped_games, successful_backups = update_result
        message_box = QMessageBox(self)
        message_box.setWindowTitle("DLSS Updater - Update Summary")
        message_box.setIcon(QMessageBox.Icon.Information)

        summary_text = ""
        if updated_games:
            summary_text += "Games updated successfully:\n"
            for dll_path, launcher, dll_type in updated_games:
                game_name = extract_game_name(dll_path, launcher)
                summary_text += f" - {game_name} - {launcher} ({dll_type})\n"
        else:
            summary_text += "No games were updated.\n"

        if successful_backups:
            summary_text += "\nSuccessful backups:\n"
            for dll_path, backup_path in successful_backups:
                game_name = extract_game_name(dll_path, "Unknown")
                dll_type = DLL_TYPE_MAP.get(
                    Path(dll_path).name.lower(), "Unknown DLL type"
                )
                summary_text += f" - {game_name}: {backup_path} ({dll_type})\n"
        else:
            summary_text += "\nNo backups were created.\n"

        if skipped_games:
            summary_text += "\nGames skipped:\n"
            for dll_path, launcher, reason, dll_type in skipped_games:
                game_name = extract_game_name(dll_path, launcher)
                summary_text += (
                    f" - {game_name} - {launcher} ({dll_type}) (Reason: {reason})\n"
                )

        message_box.setText(summary_text)
        message_box.exec()

    def apply_dark_theme(self):
        """Apply a dark theme using stylesheets."""
        dark_stylesheet = """
            QMainWindow {
                background-color: #2E2E2E; /* Dark background */
                color: #FFFFFF; /* White text */
            }
            QPushButton {
                background-color: #4D4D4D; /* Button background */
                color: #FFFFFF; /* Button text color */
                border: 1px solid #7F7F7F; /* Button border */
                padding: 5px;
            }
            QPushButton:hover {
                background-color: #5A5A5A; /* Button hover effect */
            }
            QTextBrowser {
                background-color: #3C3C3C; /* Text browser background */
                color: #FFFFFF; /* Text color */
                border: 1px solid #7F7F7F; /* Text browser border */
            }
            QMenu {
                background-color: #3C3C3C;
                color: #FFFFFF;
                border: 1px solid #7F7F7F;
            }
            QMenu::item:selected {
                background-color: #5A5A5A;
            }
        """
        self.setStyleSheet(dark_stylesheet)

        # Apply consistent styling to all launcher buttons
        button_style = """
                                QPushButton {
                                    background-color: #4D4D4D;
                                    color: white;
                                    border: 1px solid #7F7F7F;
                                    border-radius: 4px;
                                    padding: 8px 16px;
                                    text-align: left;
                                    margin: 2px 0px;
                                }
                                QPushButton:hover {
                                    background-color: #5A5A5A;
                                    border-color: #999999;
                                }
                                QPushButton:pressed {
                                    background-color: #444444;
                                }
                                QPushButton:disabled {
                                    background-color: #3D3D3D;
                                    color: #888888;
                                }
                            """

        for button in self.button_list:
            button.setStyleSheet(button_style)

        self.start_update_button.setStyleSheet(
            """
                    QPushButton {
                        background-color: #2D5A88;
                        color: white;
                        border: 1px solid #7F7F7F;
                        border-radius: 4px;
                        padding: 8px 16px;
                        text-align: left;
                        font-weight: bold;
                        margin: 2px 0px;
                    }
                    QPushButton:hover {
                        background-color: #366BA3;
                        border-color: #999999;
                    }
                    QPushButton:pressed {
                        background-color: #244B73;
                    }
                    QPushButton:disabled {
                        background-color: #1D3D5A;
                        color: #888888;
                    }
                """
        )
tools\_internal\dlss_updater\scanner.py
import os
from pathlib import Path
from .config import LauncherPathName, config_manager
from .whitelist import is_whitelisted
from dlss_updater.logger import setup_logger
import sys

logger = setup_logger()


def get_steam_install_path():
    try:
        if config_manager.check_path_value(LauncherPathName.STEAM):
            path = config_manager.check_path_value(LauncherPathName.STEAM)
            # Remove \steamapps\common if it exists
            path = path.replace("\\steamapps\\common", "")
            logger.debug(f"Using configured Steam path: {path}")
            return path

        import winreg

        key = winreg.OpenKey(
            winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\WOW6432Node\Valve\Steam"
        )
        value, _ = winreg.QueryValueEx(key, "InstallPath")
        config_manager.update_launcher_path(LauncherPathName.STEAM, str(value))
        return value
    except (FileNotFoundError, ImportError) as e:
        logger.debug(f"Could not find Steam install path: {e}")
        return None


def get_steam_libraries(steam_path):
    logger.debug(f"Looking for Steam libraries in: {steam_path}")
    library_folders_path = Path(steam_path) / "steamapps" / "libraryfolders.vdf"
    logger.debug(f"Checking libraryfolders.vdf at: {library_folders_path}")

    if not library_folders_path.exists():
        default_path = Path(steam_path) / "steamapps" / "common"
        logger.debug(
            f"libraryfolders.vdf not found, using default path: {default_path}"
        )
        return [default_path]

    libraries = []
    with library_folders_path.open("r", encoding="utf-8") as file:
        lines = file.readlines()
        for line in lines:
            if "path" in line:
                path = line.split('"')[3]
                library_path = Path(path) / "steamapps" / "common"
                logger.debug(f"Found Steam library: {library_path}")
                libraries.append(library_path)

    return libraries


def find_dlss_dlls(library_paths, launcher_name):
    """
    Find DLSS DLLs in the given list of library paths.
    """
    dll_names = ["nvngx_dlss.dll", "nvngx_dlssg.dll", "nvngx_dlssd.dll"]
    dll_paths = []
    logger.debug(f"Searching for DLLs in {launcher_name}")

    for library_path in library_paths:
        logger.debug(f"Scanning directory: {library_path}")
        try:
            for root, _, files in os.walk(library_path):
                for dll_name in dll_names:
                    if dll_name.lower() in [f.lower() for f in files]:
                        dll_path = os.path.join(root, dll_name)
                        logger.debug(f"Found DLL: {dll_path}")
                        if not is_whitelisted(dll_path):
                            logger.info(
                                f"Found non-whitelisted DLSS DLL in {launcher_name}: {dll_path}"
                            )
                            dll_paths.append(dll_path)
                        else:
                            logger.info(
                                f"Skipped whitelisted game in {launcher_name}: {dll_path}"
                            )
        except Exception as e:
            logger.error(f"Error scanning {library_path}: {e}")

    return dll_paths


def get_ea_games():
    """
    Find EA game directories and DLSS DLLs within the given path.
    """
    ea_path = config_manager.check_path_value(LauncherPathName.EA)
    ea_games_paths = []
    ea_dll_paths = []

    if ea_path and ea_path != "":
        for root, dirs, files in os.walk(ea_path):
            for file in files:
                if file.lower() in [
                    "nvngx_dlss.dll",
                    "nvngx_dlssg.dll",
                    "nvngx_dlssd.dll",
                ]:
                    dll_path = os.path.join(root, file)
                    ea_dll_paths.append(dll_path)
                    logger.debug(f"Found EA DLSS DLL: {dll_path}")

            for dir in dirs:
                if dir.lower() == "ea games":
                    games_path = os.path.join(root, dir)
                    ea_games_paths.append(games_path)
                    logger.debug(f"Found EA games directory: {games_path}")

    return ea_games_paths, ea_dll_paths


def get_ubisoft_install_path():
    try:
        if config_manager.check_path_value(LauncherPathName.UBISOFT):
            return config_manager.check_path_value(LauncherPathName.UBISOFT)
        import winreg

        key = winreg.OpenKey(
            winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\WOW6432Node\Ubisoft\Launcher"
        )
        value, _ = winreg.QueryValueEx(key, "InstallDir")
        config_manager.update_launcher_path(LauncherPathName.UBISOFT, str(value))
        logger.debug(f"Ubisoft install path: {value}")
        return value
    except (FileNotFoundError, ImportError):
        logger.error("Could not find Ubisoft install path")
        return None


def get_ubisoft_games(ubisoft_path):
    """
    Find Ubisoft game directories and DLSS DLLs within the given path.
    """
    ubisoft_games_paths = []
    ubisoft_dll_paths = []

    for root, dirs, files in os.walk(ubisoft_path):
        for file in files:
            if file.lower() in ["nvngx_dlss.dll", "nvngx_dlssg.dll", "nvngx_dlssd.dll"]:
                dll_path = os.path.join(root, file)
                ubisoft_dll_paths.append(dll_path)
                logger.debug(f"Found Ubisoft DLSS DLL: {dll_path}")

        for dir in dirs:
            if dir.lower() == "games":
                games_path = os.path.join(root, dir)
                ubisoft_games_paths.append(games_path)
                logger.debug(f"Found Ubisoft games directory: {games_path}")

    return ubisoft_games_paths, ubisoft_dll_paths


def get_xbox_games():
    """
    Find Xbox game directories and DLSS DLLs within the given path.
    """
    xbox_path = config_manager.check_path_value(LauncherPathName.XBOX)
    xbox_games_paths = []
    xbox_dll_paths = []

    if xbox_path and xbox_path != "":
        for root, dirs, files in os.walk(xbox_path):
            for file in files:
                if file.lower() in [
                    "nvngx_dlss.dll",
                    "nvngx_dlssg.dll",
                    "nvngx_dlssd.dll",
                ]:
                    dll_path = os.path.join(root, file)
                    xbox_dll_paths.append(dll_path)
                    logger.debug(f"Found Xbox DLSS DLL: {dll_path}")

            for dir in dirs:
                if dir.lower() == "games":
                    games_path = os.path.join(root, dir)
                    xbox_games_paths.append(games_path)
                    logger.debug(f"Found Xbox games directory: {games_path}")

    return xbox_games_paths, xbox_dll_paths


def get_epic_games():
    """
    Find Epic Games directories and DLSS DLLs within the given path.
    """
    epic_path = config_manager.check_path_value(LauncherPathName.EPIC)
    epic_games_paths = []
    epic_dll_paths = []

    if epic_path and epic_path != "":
        for root, dirs, files in os.walk(epic_path):
            for file in files:
                if file.lower() in [
                    "nvngx_dlss.dll",
                    "nvngx_dlssg.dll",
                    "nvngx_dlssd.dll",
                ]:
                    dll_path = os.path.join(root, file)
                    epic_dll_paths.append(dll_path)
                    logger.debug(f"Found Epic Games DLSS DLL: {dll_path}")

            for dir in dirs:
                if dir.lower() == "games":
                    games_path = os.path.join(root, dir)
                    epic_games_paths.append(games_path)
                    logger.debug(f"Found Epic Games directory: {games_path}")

    return epic_games_paths, epic_dll_paths


def get_gog_games():
    """
    Find GOG game directories and DLSS DLLs within the given path.
    """
    gog_path = config_manager.check_path_value(LauncherPathName.GOG)
    gog_games_paths = []
    gog_dll_paths = []

    if gog_path and gog_path != "":
        for root, dirs, files in os.walk(gog_path):
            for file in files:
                if file.lower() in [
                    "nvngx_dlss.dll",
                    "nvngx_dlssg.dll",
                    "nvngx_dlssd.dll",
                ]:
                    dll_path = os.path.join(root, file)
                    gog_dll_paths.append(dll_path)
                    logger.debug(f"Found GOG DLSS DLL: {dll_path}")

            for dir in dirs:
                if dir.lower() == "games":
                    games_path = os.path.join(root, dir)
                    gog_games_paths.append(games_path)
                    logger.debug(f"Found GOG games directory: {games_path}")

    return gog_games_paths, gog_dll_paths


def get_battlenet_games(battlenet_path):
    """
    Find Battle.net game directories and DLSS DLLs within the given path.
    """
    battlenet_games_paths = []
    battlenet_dll_paths = []

    for root, dirs, files in os.walk(battlenet_path):
        for file in files:
            if file.lower() in ["nvngx_dlss.dll", "nvngx_dlssg.dll", "nvngx_dlssd.dll"]:
                dll_path = os.path.join(root, file)
                battlenet_dll_paths.append(dll_path)
                logger.debug(f"Found Battle.net DLSS DLL: {dll_path}")

        for dir in dirs:
            if dir.lower() == "games":
                games_path = os.path.join(root, dir)
                battlenet_games_paths.append(games_path)
                logger.debug(f"Found Battle.net games directory: {games_path}")

    return battlenet_games_paths, battlenet_dll_paths


def find_all_dlss_dlls():
    logger.info("Starting find_all_dlss_dlls function")
    all_dll_paths = {
        "Steam": [],
        "EA Launcher": [],
        "Ubisoft Launcher": [],
        "Epic Games Launcher": [],
        "GOG Launcher": [],
        "Battle.net Launcher": [],
        "Xbox Launcher": [],
    }

    # Steam
    steam_path = get_steam_install_path()
    if steam_path:
        steam_libraries = get_steam_libraries(steam_path)
        all_dll_paths["Steam"] = find_dlss_dlls(steam_libraries, "Steam")

    # EA
    ea_games, ea_dlls = get_ea_games()
    if ea_games:
        all_dll_paths["EA Launcher"].extend(ea_dlls)

    # Ubisoft
    ubisoft_path = get_ubisoft_install_path()
    if ubisoft_path:
        ubisoft_games, ubisoft_dlls = get_ubisoft_games(ubisoft_path)
        all_dll_paths["Ubisoft Launcher"].extend(ubisoft_dlls)

    # Epic Games
    epic_games, epic_dlls = get_epic_games()
    if epic_games:
        all_dll_paths["Epic Games Launcher"].extend(epic_dlls)

    # Xbox
    xbox_games, xbox_dlls = get_xbox_games()
    if xbox_games:
        all_dll_paths["Xbox Launcher"].extend(xbox_dlls)

    # GOG
    gog_games, gog_dlls = get_gog_games()
    if gog_games:
        all_dll_paths["GOG Launcher"].extend(gog_dlls)

    # Battle.net
    battlenet_path = config_manager.check_path_value(LauncherPathName.BATTLENET)
    if battlenet_path:
        battlenet_games, battlenet_dlls = get_battlenet_games(battlenet_path)
        all_dll_paths["Battle.net Launcher"].extend(battlenet_dlls)

    # Remove duplicates
    for launcher in all_dll_paths:
        all_dll_paths[launcher] = list(set(all_dll_paths[launcher]))

    return all_dll_paths
tools\_internal\dlss_updater\updater.py
import os
import shutil
import pefile
from dlss_updater.config import LATEST_DLL_VERSIONS, LATEST_DLL_PATHS
from pathlib import Path
import stat
import time
import psutil
from packaging import version
from .logger import setup_logger
from .constants import DLL_TYPE_MAP

logger = setup_logger()


def parse_version(version_string):
    # Replace commas with dots and remove any trailing zeros
    cleaned_version = ".".join(version_string.replace(",", ".").split(".")[:3])
    return version.parse(cleaned_version)


def get_dll_version(dll_path):
    try:
        with open(dll_path, "rb") as file:
            pe = pefile.PE(data=file.read())
            for fileinfo in pe.FileInfo:
                for entry in fileinfo:
                    if hasattr(entry, "StringTable"):
                        for st in entry.StringTable:
                            for key, value in st.entries.items():
                                if key == b"FileVersion":
                                    return value.decode("utf-8").strip()
    except Exception as e:
        logger.error(f"Error reading version from {dll_path}: {e}")
    return None


def remove_read_only(file_path):
    if not os.access(file_path, os.W_OK):
        logger.info(f"Removing read-only attribute from {file_path}")
        os.chmod(file_path, stat.S_IWRITE)


def restore_permissions(file_path, original_permissions):
    os.chmod(file_path, original_permissions)


def is_file_in_use(file_path, timeout=5):
    start_time = time.time()
    while time.time() - start_time < timeout:
        try:
            with open(file_path, "rb"):
                return False
        except PermissionError:
            for proc in psutil.process_iter(["pid", "name", "open_files"]):
                try:
                    for file in proc.open_files():
                        if file.path == file_path:
                            logger.error(
                                f"File {file_path} is in use by process {proc.name()} (PID: {proc.pid})"
                            )
                            return True
                except (psutil.NoSuchProcess, psutil.AccessDenied):
                    pass
        time.sleep(0.1)
    logger.info(f"Timeout reached while checking if file {file_path} is in use")
    return True  # Assume file is NOT in use if we can't determine otherwise to prevent hanging conditions


def normalize_path(path):
    return os.path.normpath(path)


def create_backup(dll_path):
    backup_path = dll_path.with_suffix(".dlsss")
    try:
        logger.info(f"Attempting to create backup at: {backup_path}")
        if backup_path.exists():
            logger.info("Previous backup exists, removing...")
            try:
                os.chmod(backup_path, stat.S_IWRITE)
                os.remove(backup_path)
                logger.info("Successfully removed old backup")
            except Exception as e:
                logger.error(f"Failed to remove old backup: {e}")
                return None

        dir_path = os.path.dirname(backup_path)
        os.chmod(dir_path, stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC)

        shutil.copy2(dll_path, backup_path)

        if backup_path.exists():
            os.chmod(backup_path, stat.S_IWRITE | stat.S_IREAD)
            logger.info(f"Successfully created backup at: {backup_path}")
            return backup_path
        else:
            logger.error("Backup file not created")
            return None
    except Exception as e:
        logger.error(f"Failed to create backup for {dll_path}: {e}")
        logger.error(f"Error type: {type(e)}")
        return None


def update_dll(dll_path, latest_dll_path):
    dll_path = Path(normalize_path(dll_path)).resolve()
    latest_dll_path = Path(normalize_path(latest_dll_path)).resolve()
    logger.info(f"Checking DLL at {dll_path}...")

    dll_type = DLL_TYPE_MAP.get(dll_path.name.lower(), "Unknown DLL type")
    original_permissions = os.stat(dll_path).st_mode

    try:
        existing_version = get_dll_version(dll_path)
        latest_version = get_dll_version(latest_dll_path)

        if existing_version and latest_version:
            existing_parsed = parse_version(existing_version)
            latest_parsed = parse_version(latest_version)

            logger.info(
                f"Existing version: {existing_version}, Latest version: {latest_version}"
            )
            # Do not include FG/RR DLLs in the update check
            if dll_type == "nvngx_dlss.dll" and existing_parsed < parse_version("2.0.0"):
                logger.info(
                    f"Skipping update for {dll_path}: Version {existing_version} is less than 2.0.0 and cannot be updated."
                )
                return False, None, dll_type

            if existing_parsed >= latest_parsed:
                logger.info(
                    f"{dll_path} is already up-to-date (version {existing_version})."
                )
                return False, None, dll_type

        if not dll_path.exists():
            logger.error(f"Error: Target DLL path does not exist: {dll_path}")
            return False, None, dll_type

        if not latest_dll_path.exists():
            logger.error(f"Error: Latest DLL path does not exist: {latest_dll_path}")
            return False, None, dll_type

        if not os.access(dll_path.parent, os.W_OK):
            logger.error(
                f"Error: No write permission to the directory: {dll_path.parent}"
            )
            return False, None, dll_type

        backup_path = create_backup(dll_path)
        if not backup_path:
            return False, None, dll_type

        remove_read_only(dll_path)

        retry_count = 3
        while retry_count > 0:
            if not is_file_in_use(str(dll_path)):
                break
            logger.info(
                f"File is in use. Retrying in 2 seconds... (Attempts left: {retry_count})"
            )
            time.sleep(2)
            retry_count -= 1

        if retry_count == 0:
            logger.info(
                f"File {dll_path} is still in use after multiple attempts. Cannot update."
            )
            restore_permissions(dll_path, original_permissions)
            return False, None, dll_type

        try:
            os.remove(dll_path)
            shutil.copyfile(latest_dll_path, dll_path)
            restore_permissions(dll_path, original_permissions)

            # Verify update
            new_version = get_dll_version(dll_path)
            if new_version == latest_version:
                logger.info(
                    f"Successfully updated {dll_path} from version {existing_version} to {latest_version}."
                )
                return True, backup_path, dll_type
            else:
                logger.error(
                    f"Version verification failed - Expected: {latest_version}, Got: {new_version}"
                )
                return False, backup_path, dll_type

        except Exception as e:
            logger.error(f"File update operation failed: {e}")
            if backup_path and backup_path.exists():
                try:
                    shutil.copyfile(backup_path, dll_path)
                    logger.info("Restored backup after failed update")
                except Exception as restore_error:
                    logger.error(f"Failed to restore backup: {restore_error}")
            return False, backup_path, dll_type

    except Exception as e:
        logger.error(f"Error updating {dll_path}: {e}")
        restore_permissions(dll_path, original_permissions)
        return False, None, dll_type
tools\_internal\dlss_updater\utils.py
import os
import sys
from pathlib import Path
import ctypes
from dlss_updater.logger import setup_logger


logger = setup_logger()


try:
    from dlss_updater import (
        update_dll,
        is_whitelisted,
        __version__,
        LATEST_DLL_PATHS,
        DLL_TYPE_MAP,
        find_all_dlss_dlls,
        auto_update,
        resource_path,
    )
except ImportError as e:
    logger.error(f"Error importing dlss_updater modules: {e}")
    logger.error("Current sys.path:")
    for path in sys.path:
        logger.error(path)
    logger.error("\nCurrent directory contents:")
    for item in os.listdir():
        logger.error(item)
    logger.error("\ndlss_updater directory contents:")
    try:
        for item in os.listdir("dlss_updater"):
            logger.error(item)
    except FileNotFoundError:
        logger.error("dlss_updater directory not found")
    sys.exit(1)


def find_file_in_directory(directory, filename):
    for root, _, files in os.walk(directory):
        if filename in files:
            return os.path.join(root, filename)
    return None


def check_update_completion():
    update_log_path = os.path.join(os.path.dirname(sys.executable), "update_log.txt")
    if os.path.exists(update_log_path):
        with open(update_log_path, "r") as f:
            logger.info(f"Update completed: {f.read()}")
        os.remove(update_log_path)


def check_update_error():
    error_log_path = os.path.join(
        os.path.dirname(sys.executable), "update_error_log.txt"
    )
    if os.path.exists(error_log_path):
        with open(error_log_path, "r") as f:
            logger.error(f"Update error occurred: {f.read()}")
        os.remove(error_log_path)


def check_dependencies():
    try:
        from importlib.metadata import distributions

        required = {"pefile", "psutil"}
        installed = set()
        for dist in distributions():
            name = dist.metadata.get("Name")
            if name:
                installed.add(name.lower())
        missing = required - installed
        if missing:
            logger.info(f"Missing dependencies: {', '.join(missing)}")
            return False
        return True
    except ImportError:
        logger.error("Unable to check dependencies. Proceeding anyway.")
        return True


def run_as_admin():
    script = Path(sys.argv[0]).resolve()
    params = " ".join([str(script)] + sys.argv[1:])
    logger.info("Re-running script with admin privileges...")
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, params, None, 1)


def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False


def extract_game_name(dll_path, launcher_name):
    parts = Path(dll_path).parts
    try:
        if "steamapps" in parts:
            return parts[parts.index("steamapps") + 2]
        elif "EA Games" in parts:
            return parts[parts.index("EA Games") + 1]
        elif "Ubisoft Game Launcher" in parts:
            return parts[parts.index("games") + 1]
        elif "Epic Games" in parts:
            return parts[parts.index("Epic Games") + 2]
        elif "GOG Galaxy" in parts:
            return parts[parts.index("Games") + 1]
        elif "Battle.net" in parts:
            return parts[parts.index("Battle.net") + 1]
        else:
            # If we can't determine the game name, use the parent directory name
            return parts[-2]
    except (ValueError, IndexError) as e:
        logger.error(
            f"Error extracting game name for {dll_path} in {launcher_name}: {e}"
        )
        return "Unknown Game"


def update_dlss_versions():
    logger.info(f"DLSS Updater version {__version__}")
    logger.info("Starting DLL search...")
    
    updated_games = []
    skipped_games = []
    successful_backups = []

    try:
        logger.info("Checking for updates...")
        if auto_update is None:
            logger.info("No updates were found.")
        else:
            try:
                update_available = auto_update()
                if update_available:
                    logger.info(
                        "The application will now close for the update. If the update does NOT automatically restart, please manually reboot it from the /update/ folder."
                    )
                    return True, [], [], []  # Early return for auto-update
            except Exception as e:
                logger.error(f"Error during update check: {e}")
                import traceback
                traceback.print_exc()

        try:
            all_dll_paths = find_all_dlss_dlls()
            logger.info("DLL search completed.")
        except Exception as e:
            logger.error(f"Error finding DLLs: {e}")
            return False, [], [], []

        processed_dlls = set()

        if any(all_dll_paths.values()):
            logger.info("\nFound DLLs in the following launchers:")
            # Process each launcher
            for launcher, dll_paths in all_dll_paths.items():
                if dll_paths:
                    logger.info(f"{launcher}:")
                    for dll_path in dll_paths:
                        try:
                            dll_path = Path(dll_path) if isinstance(dll_path, str) else dll_path
                            if str(dll_path) not in processed_dlls:
                                result = process_single_dll(dll_path, launcher)
                                if result:
                                    success, backup_path, dll_type = result
                                    if success:
                                        logger.info(f"Successfully processed: {dll_path}")
                                        updated_games.append((str(dll_path), launcher, dll_type))
                                        if backup_path:
                                            successful_backups.append((str(dll_path), backup_path))
                                    else:
                                        if backup_path:  # Attempted but failed
                                            skipped_games.append((str(dll_path), launcher, "Update failed", dll_type))
                                        else:  # Skipped for other reasons
                                            skipped_games.append((str(dll_path), launcher, "Skipped", dll_type))
                                processed_dlls.add(str(dll_path))
                        except Exception as e:
                            logger.error(f"Error processing DLL {dll_path}: {e}")
                            continue

            # Display summary after processing
            if updated_games:
                logger.info("\nGames updated successfully:")
                for dll_path, launcher, dll_type in updated_games:
                    game_name = extract_game_name(dll_path, launcher)
                    logger.info(f" - {game_name} - {launcher} ({dll_type})")
            else:
                logger.info("\nNo games were updated.")

            if successful_backups:
                logger.info("\nSuccessful backups:")
                for dll_path, backup_path in successful_backups:
                    game_name = extract_game_name(dll_path, "Unknown")
                    dll_type = DLL_TYPE_MAP.get(Path(dll_path).name.lower(), "Unknown DLL type")
                    logger.info(f" - {game_name}: {backup_path} ({dll_type})")
            else:
                logger.info("\nNo backups were created.")

            if skipped_games:
                logger.info("\nGames skipped:")
                for dll_path, launcher, reason, dll_type in skipped_games:
                    game_name = extract_game_name(dll_path, launcher)
                    logger.info(f" - {game_name} - {launcher} ({dll_type}) (Reason: {reason})")
        else:
            logger.info("No DLLs were found or processed.")

        return True, updated_games, skipped_games, successful_backups

    except Exception as e:
        import traceback
        trace = traceback.format_exc()
        logger.error(f"Critical error in update process: {e}")
        logger.error(f"Traceback:\n{trace}")
        return False, [], [], []


def process_single_dll(dll_path, launcher):
    """Process a single DLL file"""
    try:
        dll_type = DLL_TYPE_MAP.get(dll_path.name.lower(), "Unknown DLL type")
        logger.info(f" - {dll_type}: {dll_path}")

        game_name = extract_game_name(str(dll_path), launcher)
        if "warframe" in game_name.lower():
            return None

        if is_whitelisted(str(dll_path)):
            return False, None, dll_type

        dll_name = dll_path.name.lower()
        if dll_name in LATEST_DLL_PATHS:
            latest_dll_path = LATEST_DLL_PATHS[dll_name]
            return update_dll(str(dll_path), latest_dll_path)

        return False, None, dll_type
    except Exception as e:
        logger.error(f"Error processing DLL {dll_path}: {e}")
        return False, None, "Error"


def display_update_summary(updated_games, skipped_games, successful_backups):
    """Display a summary of the update process"""
    logger.info("\nSummary:")
    if not (updated_games or skipped_games or successful_backups):
        logger.info("No DLLs were found or processed.")
        return

    if updated_games:
        logger.info("\nGames updated successfully:")
        for dll_path, launcher, dll_type in updated_games:
            game_name = extract_game_name(dll_path, launcher)
            logger.info(f" - {game_name} - {launcher} ({dll_type})")
    else:
        logger.info("\nNo games were updated.")

    if successful_backups:
        logger.info("\nSuccessful backups:")
        for dll_path, backup_path in successful_backups:
            game_name = extract_game_name(dll_path, "Unknown")
            dll_type = DLL_TYPE_MAP.get(Path(dll_path).name.lower(), "Unknown DLL type")
            logger.info(f" - {game_name}: {backup_path} ({dll_type})")
    else:
        logger.info("\nNo backups were created.")

    if skipped_games:
        logger.info("\nGames skipped:")
        for dll_path, launcher, reason, dll_type in skipped_games:
            game_name = extract_game_name(dll_path, launcher)
            logger.info(f" - {game_name} - {launcher} ({dll_type}) (Reason: {reason})")
tools\_internal\dlss_updater\version.py
__version__ = "2.6.7"
tools\_internal\dlss_updater\whitelist.py
import os
import csv
from io import StringIO
from urllib.request import urlopen
from urllib.error import URLError
from dlss_updater.logger import setup_logger

logger = setup_logger()

WHITELIST_URL = (
    "https://raw.githubusercontent.com/Recol/DLSS-Updater-Whitelist/main/whitelist.csv"
)


def fetch_whitelist():
    try:
        with urlopen(WHITELIST_URL) as response:
            csv_data = StringIO(response.read().decode("utf-8"))
        reader = csv.reader(csv_data)
        return set(row[0].strip() for row in reader if row and row[0].strip())
    except URLError as e:
        logger.error(f"Failed to fetch whitelist: {e}")
        return set()
    except csv.Error as e:
        logger.error(f"Failed to parse whitelist CSV: {e}")
        return set()


WHITELISTED_GAMES = fetch_whitelist()


def is_whitelisted(game_path):
    """Check if a game path matches any whitelisted games"""
    logger.debug(f"Checking game against whitelist: {game_path}")
    path_parts = game_path.lower().split(os.path.sep)
    game_name = path_parts[-1] if len(path_parts) > 1 else "Unknown"

    for game in WHITELISTED_GAMES:
        game_words = game.lower().split()
        if all(word in " ".join(path_parts) for word in game_words):
            logger.info(f"Whitelist match found: {game_name} matches {game}")
            return True

    logger.debug(f"No whitelist match found for: {game_name}")
    return False
tools\_internal\dlss_updater\__init__.py
from .scanner import get_steam_install_path, get_steam_libraries, find_dlss_dlls, find_all_dlss_dlls
from .updater import update_dll
from .whitelist import is_whitelisted
from .version import __version__
from .config import LATEST_DLL_PATHS, resource_path
from .auto_updater import auto_update
from .logger import setup_logger
from .constants import DLL_TYPE_MAP
from .lib.threading_lib import ThreadManager, WorkerSignals

__all__ = [
    "get_steam_install_path",
    "get_steam_libraries",
    "find_dlss_dlls",
    "find_all_dlss_dlls",
    "update_dll",
    "is_whitelisted",
    "__version__",
    "LATEST_DLL_PATHS",
    "resource_path",
    "auto_update",
    "setup_logger",
    "DLL_TYPE_MAP",
    "ThreadManager",
    "WorkerSignals",
]
tools\_internal\icons\battlenet.png
 
tools\_internal\icons\dlss_updater.png
 
tools\_internal\icons\dlss_updater_full.png
 
tools\_internal\icons\ea.png
 
tools\_internal\icons\epic.png
 
tools\_internal\icons\gog.png
 
tools\_internal\icons\reset.png
 
tools\_internal\icons\steam.png
 
tools\_internal\icons\ubisoft.png
 
tools\_internal\icons\update.png
 
tools\_internal\icons\xbox.png
 
tools\_internal\latest_dll\nvngx_dlss.dll
md5: 3A875F45C315D09E5F4548CC9288F178 | sha1: 064709DA803D9A796C2E4AC17B5F904522C4F646 | sha256: 4E85CDBE0896AAB5F12C29F0B66AE7E5D9622CFADAC37AA9852ACBA8E4861F5A | sha512: 9628969F053F9DA54D84422BF8E0915EDC7129379AA49B4D12969628E7599BE256D1FE3EDD18AAE32C7A837C82DEE30E8C28EDD8C8246B240F76CF2103A12980
tools\_internal\latest_dll\nvngx_dlssd.dll
md5: E6081B848EA68880DB8ADC83CDFB15DC | sha1: B9985D09D60A78B5D32412226FC1E67A44977FCD | sha256: 892D335AE0C5795A0AF870AF1B7107011733773635FE5070819AFF2C7D622739 | sha512: E5730FCC0193EB030E7922CC8DED64BFA3143DA24F79478FAF4C30493F9434C0661D715A36D29C53D371C0AFE3E6D2309501E185F10CC4AAE69876168C52C03A
tools\_internal\latest_dll\nvngx_dlssg.dll
md5: 26C2EAFE046CDD403A1850F71186595C | sha1: 2BD904FE67D609E9374897B65BB34033A3F8C89A | sha256: 245FDF1DF96E46A2303A46EC837063E662136E279E9AF60B217798EA7366D385 | sha512: D98B64F17BFA7CD5F91A3A2BD38C8E3AE65AE2427571BD1710388C040C52639F82E70FA0741DC8D190FE6C653914942AEA36D7D4EFF1655C01808824684044BB
tools\_internal\libcrypto-3.dll
md5: 123AD0908C76CCBA4789C084F7A6B8D0 | sha1: 86DE58289C8200ED8C1FC51D5F00E38E32C1AAD5 | sha256: 4E5D5D20D6D31E72AB341C81E97B89E514326C4C861B48638243BDF0918CFA43 | sha512: 80FAE0533BA9A2F5FA7806E86F0DB8B6AAB32620DDE33B70A3596938B529F3822856DE75BDDB1B06721F8556EC139D784BC0BB9C8DA0D391DF2C20A80D33CB04
tools\_internal\libffi-8.dll
md5: 0F8E4992CA92BAAF54CC0B43AACCCE21 | sha1: C7300975DF267B1D6ADCBAC0AC93FD7B1AB49BD2 | sha256: EFF52743773EB550FCC6CE3EFC37C85724502233B6B002A35496D828BD7B280A | sha512: 6E1B223462DC124279BFCA74FD2C66FE18B368FFBCA540C84E82E0F5BCBEA0E10CC243975574FA95ACE437B9D8B03A446ED5EE0C9B1B094147CEFAF704DFE978
tools\_internal\libssl-3.dll
md5: 4FF168AAA6A1D68E7957175C8513F3A2 | sha1: 782F886709FEBC8C7CEBCEC4D92C66C4D5DBCF57 | sha256: 2E4D35B681A172D3298CAF7DC670451BE7A8BA27C26446EFC67470742497A950 | sha512: C372B759B8C7817F2CBB78ECCC5A42FA80BDD8D549965BD925A97C3EEBDCE0335FBFEC3995430064DEAD0F4DB68EBB0134EB686A0BE195630C49F84B468113E3
tools\_internal\pefile-2023.2.7.dist-info\INSTALLER
 
tools\_internal\pefile-2023.2.7.dist-info\LICENSE
 
tools\_internal\pefile-2023.2.7.dist-info\METADATA
tools\_internal\pefile-2023.2.7.dist-info\RECORD
 
tools\_internal\pefile-2023.2.7.dist-info\REQUESTED
 
tools\_internal\pefile-2023.2.7.dist-info\top_level.txt
ordlookup
pefile
peutils
tools\_internal\pefile-2023.2.7.dist-info\WHEEL
 
tools\_internal\psutil-6.1.1.dist-info\INSTALLER
 
tools\_internal\psutil-6.1.1.dist-info\LICENSE
 
tools\_internal\psutil-6.1.1.dist-info\METADATA
tools\_internal\psutil-6.1.1.dist-info\RECORD
 
tools\_internal\psutil-6.1.1.dist-info\REQUESTED
 
tools\_internal\psutil-6.1.1.dist-info\top_level.txt
psutil
tools\_internal\psutil-6.1.1.dist-info\WHEEL
 
tools\_internal\psutil\_psutil_windows.pyd
md5: 7A9632D241AD8B97BB50E8EF6DAC1CA6 | sha1: 29F0D5DE91A84FA58CF45FD134358254B7DA12ED | sha256: DD0CCDEECA681645025CA0F562EA45B5B17A1EBFCF1688CD0647A950A2992E2F | sha512: CA6AE6493961F722C07B2FACF272CAF428FD6BCD51A01C34271A18C5D898409C400E50BBAAB2771CBDC94B20041668BE8137242995C9096E511F635F1EA80BB9
tools\_internal\pyexpat.pyd
md5: 03493D1441671ABE9339AF942253DAC3 | sha1: 0D8800BE2733BB56FB2909A6F9389C00EB00F612 | sha256: 3A4830342AB562E41AB93B4BC2DC45FE0AB760815E7C3EC4A7FDDC914EC99982 | sha512: 1B092A9E2E9E64533E7436C239961CEE4FFDE0FA6FED4C6E0CA2A9F72FC72065D457968DC92E74F4E052CD2557F6D380A86046117B6A450306A16AC6E885A036
tools\_internal\PyQt6\Qt6\bin\MSVCP140.dll
md5: 01B946A2EDC5CC166DE018DBB754B69C | sha1: DBE09B7B9AB2D1A61EF63395111D2EB9B04F0A46 | sha256: 88F55D86B50B0A7E55E71AD2D8F7552146BA26E927230DAF2E26AD3A971973C5 | sha512: 65DC3F32FAF30E62DFDECB72775DF870AF4C3A32A0BF576ED1AAAE4B16AC6897B62B19E01DC2BF46F46FBE3F475C061F79CBE987EDA583FEE1817070779860E5
tools\_internal\PyQt6\Qt6\bin\MSVCP140_1.dll
md5: 0FE6D52EB94C848FE258DC0EC9FF4C11 | sha1: 95CC74C64AB80785F3893D61A73B8A958D24DA29 | sha256: 446C48C1224C289BD3080087FE15D6759416D64F4136ADDF30086ABD5415D83F | sha512: C39A134210E314627B0F2072F4FFC9B2CE060D44D3365D11D8C1FE908B3B9403EBDD6F33E67D556BD052338D0ED3D5F16B54D628E8290FD3A155F55D36019A86
tools\_internal\PyQt6\Qt6\bin\MSVCP140_2.dll
md5: 9002E0BEE6455B2322E3E717FE25F9BE | sha1: BC8DF83CC657F0F46A0BFF20565870A435ED1563 | sha256: 24B47C966B6E4A65B3E4DF866D347D3427E9BD709BE550C38224427EB5E143D3 | sha512: 28DDD087B48D5AA96EC39CCC29A4020CF75AE3C5CB6AF9A9571694D73F7AAA4FECB15336C9C7A7D12C93D8BF12EFA4FE4D8D612CD93D72C72130CAE52317D0D9
tools\_internal\PyQt6\Qt6\bin\opengl32sw.dll
md5: 83BBECF92FB68795A620B395998B131B | sha1: 026F9E87A5623FE9370C2EEDEF24C765F7312800 | sha256: B04DE4541863BC7D8879040A78889C4849C1B1DA2784C4630F734C146C2998CE | sha512: C63CA8863F63C8F415D685EFF991A1AA67E3457AC2B1F6524DB271C2986F7E79415F98F212E1F7CDD644F41BC48D558661E1136716D63F81675F664E53FDFC70
tools\_internal\PyQt6\Qt6\bin\Qt6Core.dll
md5: F6618CDB7D96415A6E11558482E32BF8 | sha1: 03F07AF673B9838C4C488C6091D878768934E654 | sha256: FCDCC96D23D1F2F2585BC17125804D4D74DE74C8BED20CE9D6CA348A14212C44 | sha512: 656F77F2A2BBB5D0E1852EFB7854A12F706854F94C6285C1D7542E760B4586F4F6558EC0968BAE2422A11D2681408853F9FEB84B9FF221F7512AB0C53724746C
tools\_internal\PyQt6\Qt6\bin\Qt6Gui.dll
md5: 244C775000161DD8C34A08C4A477C73F | sha1: CF333FFB09EE833E555E9D33AB9B31F52D2AAAEB | sha256: EF3B36AA58C41BDBEAC8EEDA14CFFFB97C2DB5165230489F2F9733A5255BF24F | sha512: 8EE6F6BDEE7D4E7F0385DD7F7B904445126839669A592B228B46F9692A94FF796072F4264D57AADFB92472E60A7A1DE0A88675633EDDD01CF2FC433EED805DDA
tools\_internal\PyQt6\Qt6\bin\Qt6Network.dll
md5: B1113A4174AAA289CCBB199A45D6AB07 | sha1: 7A2B51C4C8832426FC8C72ED854E1AA5D7CBA447 | sha256: 621FCE49FB05297962844FE20355D26322CC340C354ACB0BF1E032709C70E213 | sha512: 84C91B064A7F9E6A48D65F5436F931E61856BF58FA970204795431563F9A27BDABDF44E7875118F9A320FECA73AF9D4564B52B498779DF7B5DCDFA6D4A995BD5
tools\_internal\PyQt6\Qt6\bin\Qt6Pdf.dll
md5: 7AEFE1D8D66BC24CF968D149C3D355BA | sha1: D6BAC71C80DA7D56A042211B08A77E9E30ABF36B | sha256: 46D8E8D293F47DA45CA9F2D5D9D84C4DFABAEC2DC525B40573EE42217BE3E7CA | sha512: 329C2DEBDD3EB5CD317FEED10557001C112DF9F1F773982AFBB6C197CFBEA235A9229C11CAF0BF8CAFA1AA72A9FF80A0B3B7E1312E7ED1C98D8692B23EDB6964
tools\_internal\PyQt6\Qt6\bin\Qt6Svg.dll
md5: EB9E66A05279C8D3DEDC3F82A440D9DF | sha1: 7409A2F56313DD4999FC24F878B4242CBF0E7685 | sha256: EBF2FDD97CD098C7DFE9F4D68D0620A22F9A38F7F5FAA943EB816B07C05AF4A9 | sha512: 990798E0A48903BAD7EC8CDE195F5796D12239E3D64D9B3F9ECE4D74B71F75AB4498C1CB59248171F9CACE8970BD115FBDF1EDCF125333539C64F9313D2F2D1B
tools\_internal\PyQt6\Qt6\bin\Qt6Widgets.dll
md5: 1FCC9650B4E10AC13B280DBB8A5F435E | sha1: D9BCAC7BFA93682A8E917E450CB727754DFCC033 | sha256: 5AED2C3A8FF118747172631F9451ECB60651854AC9A90666E3B61C8454600770 | sha512: 50A389ADBAC7BD51195F5CECAFE948B2A699B6C98B0F8DBCAD220580A580869959045A6625ED7F1DB576FDF502B28BA062A3F91FF311F055359185BAA102719B
tools\_internal\PyQt6\Qt6\bin\VCRUNTIME140.dll
md5: 971DBBE854FC6AB78C095607DFAD7B5C | sha1: 1731FB947CD85F9017A95FDA1DC5E3B0F6B42CA2 | sha256: 5E197A086B6A7711BAA09AFE4EA7C68F0E777B2FF33F1DF25A21F375B7D9693A | sha512: B966AAB9C0D9459FADA3E5E96998292D6874A7078924EA2C171F0A1A50B0784C24CC408D00852BEC48D6A01E67E41D017684631176D3E90151EC692161F1814D
tools\_internal\PyQt6\Qt6\bin\VCRUNTIME140_1.dll
md5: 6BC084255A5E9EB8DF2BCD75B4CD0777 | sha1: CF071AD4E512CD934028F005CABE06384A3954B6 | sha256: 1F0F5F2CE671E0F68CF96176721DF0E5E6F527C8CA9CFA98AA875B5A3816D460 | sha512: B822538494D13BDA947655AF791FED4DAA811F20C4B63A45246C8F3BEFA3EC37FF1AA79246C89174FE35D76FFB636FA228AFA4BDA0BD6D2C41D01228B151FD89
tools\_internal\PyQt6\Qt6\plugins\generic\qtuiotouchplugin.dll
md5: BBCE418C51906DA7797BA6B0404D7F8B | sha1: F23C6BFF9EA8AB66C7355029494E22FC17A9D645 | sha256: 91E2A12E3D4C33C688B88EFCB7F85EA7986165284E440130102025A4CC050C99 | sha512: 8A17A2E8EC56268BF014A604602416441B3DA3DB50956A309F4B8DC244F9F49FFF0D642B5D7A6580A13E4406F8D934B1696877FED93B7ADBDF93FAB5C66472E5
tools\_internal\PyQt6\Qt6\plugins\iconengines\qsvgicon.dll
md5: 04E1D1FEC94098917B19A1159FF47193 | sha1: 3CD6F0171EDFB371208750E166E9E8E090FEAFE0 | sha256: FAD7B91D3DFC311E6713C9616EECF02F69D11EF6EE94E45B08623D4AA7F827AA | sha512: 6A66AAC55303898CBC2F04E413F7A1D3F8947CAC75D1B20A05A2A4ADC7133BC050797B89E5301E683CB09EC732C5FBCA8891E7539BF6B172178DD57F34F68088
tools\_internal\PyQt6\Qt6\plugins\imageformats\qgif.dll
md5: CFEB5A9AC4A431A763184B50AAF5244D | sha1: ABD689EC12D04D62B2880138C71F8976A08166EC | sha256: 466C595B87F59053DE2957581B49104C4A2CDB2E7515E061D6C45CF6C24D17AB | sha512: 935AB2B061973B931BDC13573D9DF9F63D4BC96DD13AFA566DDDAA2484B25D2058A0D037A433E94ECA45634D67BB902AA1FC395B5B8D28B6EA462F3973223D23
tools\_internal\PyQt6\Qt6\plugins\imageformats\qicns.dll
md5: 487F07BC68C42C1F84341DE31B81339E | sha1: BBA2E85D1D659B58C1748E633B00BE12230647FA | sha256: 185A84304287C558B6CF641E707257EEC49560D9AE50307E02A7DAA7AC8F8739 | sha512: 353DB60802B59AE4AF9FC6DB789AD6C7949D331AB954448B2BD1492B05C4CB9FC4A1E005BBA73A7FEE4071A6D6128CC24CC7D7281F789742DC83B89D76E645A2
tools\_internal\PyQt6\Qt6\plugins\imageformats\qico.dll
md5: 75641F83B9F6515B473E8A2C34F037BF | sha1: 1E787105B2D3F7D573EA709E07EA998020ABAFB5 | sha256: E85A0935FFA2A1BD5425DDBDC1035E8F90E8DE2E26BD0A112F86A5895BADCB86 | sha512: FCC91417BABDDF9F215D27CBDBEE5AFEE32A74FEF1DA3A5F7C763316F80BAF30DBE0E5031F24DB8913F02F27A07516FC4D3947877827AB8752F7D3661F21E13C
tools\_internal\PyQt6\Qt6\plugins\imageformats\qjpeg.dll
md5: 14139AF7CB55653167F0C021EF550419 | sha1: AF2794D2CB7E5784C37AC900988208E857E409E1 | sha256: DF30779FA1830475C7FBED9A7CA4C2A0E8F037C53BA4B08FF9B5658B1960B4C9 | sha512: 6F3E762A2F792FE89F7A052CF76E7D51EC7C528D12622B4AAD93736D4610A41E60FC1DBF3053CDB8F2B0D9B0231DE51469B55BCE483F116DD704907157EF6CF1
tools\_internal\PyQt6\Qt6\plugins\imageformats\qpdf.dll
md5: 369D2CDF81B363395F21CAEE9AB7095F | sha1: F69C78A47BAF89FEB83D82EC1BE2909290D29C5C | sha256: FFE2BB41E5AF3BD9F3800AA60ACF9A19136CCE60CB85C850C4F54BD62303C5FF | sha512: 65DA77FB310A466C7CF9EC287AA47E9ACDA8A03E68D0F0B4A1F4EBFA039643EC27A37607A4FFB783D8CDEC4E9BBFF210059B4BCB1987FCDC883A9BFF2AA7C9C6
tools\_internal\PyQt6\Qt6\plugins\imageformats\qsvg.dll
md5: 31BB65616CB6BD7C14F7800EF35E4B0B | sha1: 605451C1199D907F602D8D91D56D1E77AA39F475 | sha256: 5CE4E822A9AB127779CE33CBBD400D311192EC2E8D33F820FE0DEF27C8D03FE5 | sha512: 404E49E4422334A5D585CDEDCEAD10703A815FFAA771D32C0B1C53BBA1E38FCE01F251F0993F7ABCAF2C7591FA029152032E040C4B68FE7EA678DD1C4CD4C2EA
tools\_internal\PyQt6\Qt6\plugins\imageformats\qtga.dll
md5: 01E6729E86BE5C3E3B14C4B50D84FB78 | sha1: CA5B4430E2CCBB6E21E61AB4A8B1907F9E65A9E2 | sha256: 8F04B3B032C801FF77838B5C8CB53D774BED1A2D8262984389BA99E4FDBF30D0 | sha512: CC1A6C4A88999FF4686535B115AA8E4E63BA1DF623B41F085B97474730936C80408060C4BE482BB9358F53DF8B56336177F1FF21521F0A22786953E1F12ED308
tools\_internal\PyQt6\Qt6\plugins\imageformats\qtiff.dll
md5: 5C421747682ADAC0511A891E109882FE | sha1: 297C8516C0A1EABF0261FDD4E69DF75BEBB0FEC9 | sha256: 553FFC35CD2BAD6FC8389F23253026E7B7C1FE21FF717310ADE1011B7EED1061 | sha512: 792C3452D1CEECC14CC1E9787340E1D72CA85E1A5D5BD244B8AC713CE9AE5771AF6E98DD9ECA2A1E48E92385A658DA32C8018C609F93416E9FEBC732BD57EEF0
tools\_internal\PyQt6\Qt6\plugins\imageformats\qwbmp.dll
md5: 2D13ADB190D04B71420F85B63ED1297C | sha1: F723111A66E54B2DE44C11DDD21B9BFF23C15F09 | sha256: FA8DCB17CB14AB3DF317E3B28754DB985491703B6EB0704FA29B4414EB8252FA | sha512: 8CE429A8380E3AB5130BAA55A794C3E51C5F3B7B2BE12C0F5094777D89A107F22ACE6BC5FA4A759FF36BC08B69CC0E0E8AE61F350DCBEFC47B08BAA8B583B64B
tools\_internal\PyQt6\Qt6\plugins\imageformats\qwebp.dll
md5: 596994BCCBF0677A1656F5A7D5DCF032 | sha1: 7C4B9C48455280BD275BA8E1C5EE6B1DAD897379 | sha256: 923DCDD83563740F8C16E8AA8CFA394DC22F570FE64A407C534BDF2258902126 | sha512: 37000D69405ECDC0816C533BF33DBD1EE5D05978BEEDAD49C2840D905759863478777B728284D45A217770E7BB3984ABE694EBFF08E319B72603A1CD628450B4
tools\_internal\PyQt6\Qt6\plugins\platforms\qminimal.dll
md5: F534EA5B2E138CF01FC63095BFED91CD | sha1: 24549EB531B077DF71A3AACCD7B9E91060049BA5 | sha256: 1F03F0A4358061B49ADE4885526DC9F4C4542B130B6BC418C60328D19A3AF553 | sha512: 903B925BC5EFE8122D3CD9A78977931FF3217E3F0137E383AB898E3FA3F088E6802B0F58F324E6B43B152158B528F17EC9D399C0D78E8B25A1B0B5A6CF1BD674
tools\_internal\PyQt6\Qt6\plugins\platforms\qoffscreen.dll
md5: 712BE32D69CCFCC5E8E07EB0B0252838 | sha1: B88372F5536D44C1D9D82FCF6C5CCADA91535891 | sha256: 01EB833A4B517073B8F443F5A99198B021CAEB207773FF405B8A421D6ED405A4 | sha512: 1F940942B80B5287272D237E6CDC7E488D322822EBC96279A922E21876B493D6BC61B520ECC3FAF23F802AF070A44D09B418EDEB28CB8C7F31962A43D7E44105
tools\_internal\PyQt6\Qt6\plugins\platforms\qwindows.dll
md5: 9E9EDE62DAC5ED360AD811C409B96EC7 | sha1: C7DC498254667728A31A2C6EBB0786708CC87E1D | sha256: F4A118AFD9259CD928F55FA87F6FBC2CD88478E79BC75F4032D650B7E01E16AA | sha512: 0D6B56B68B045FFB31E5C7B81C1AAAC78078A3F4DBD53CD569C1DF350132BDD7031847573B204AB0A0B05D1695C986E8E79A5EF4617A75C5ECB9E12231606C3B
tools\_internal\PyQt6\Qt6\plugins\styles\qmodernwindowsstyle.dll
md5: A4A3C1223C9ADB54B324586C5EE374C4 | sha1: 0797C48A2946583F29F9B0A41EC770451A3CDF6C | sha256: EC2F0B95FA11C4DFD30DB27A8E593E7FEC4281EFC1BDDB578EB4DC15B8A66DF0 | sha512: D32A572B40541D90114F694B7C14BBAD67B7EB1391D56F827A83F60F78C1235D789DAD0301196A4AB404C8B1065840AAE0E5894F7EA200577441AC225AB8019B
tools\_internal\PyQt6\Qt6\translations\qtbase_ar.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_bg.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_ca.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_cs.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_da.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_de.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_en.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_es.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_fa.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_fi.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_fr.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_gd.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_he.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_hr.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_hu.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_it.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_ja.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_ka.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_ko.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_lv.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_nl.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_nn.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_pl.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_pt_BR.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_ru.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_sk.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_tr.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_uk.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_zh_CN.qm
 
tools\_internal\PyQt6\Qt6\translations\qtbase_zh_TW.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_ar.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_bg.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_ca.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_cs.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_da.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_de.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_en.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_es.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_fa.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_fi.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_fr.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_gd.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_gl.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_he.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_ar.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_bg.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_ca.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_cs.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_da.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_de.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_en.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_es.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_fr.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_gl.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_hr.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_hu.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_it.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_ja.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_ka.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_ko.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_nl.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_nn.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_pl.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_pt_BR.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_ru.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_sk.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_sl.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_tr.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_uk.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_zh_CN.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_help_zh_TW.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_hr.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_hu.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_it.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_ja.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_ka.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_ko.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_lt.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_lv.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_nl.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_nn.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_pl.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_pt_BR.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_pt_PT.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_ru.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_sk.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_sl.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_sv.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_tr.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_uk.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_zh_CN.qm
 
tools\_internal\PyQt6\Qt6\translations\qt_zh_TW.qm
 
tools\_internal\PyQt6\QtCore.pyd
md5: C81647CFF66445F6520F4881B4D853D9 | sha1: F25458A223DE5119C6960C0F1F493FE8D1EA0AB1 | sha256: 94440B0412810D556BAFB1B92824D8531BFBB3D593E3460D6B19483322539D9D | sha512: 6C86D4759389A25B5AEBC33149D327455E83EA6A4DE3D575E5431CB7E8167824AA25CC659AE642DED6F35083E1BBC4416327D83E3471BD509A612CE0D211CC76
tools\_internal\PyQt6\QtGui.pyd
md5: 008E1FE88263CDC69853DCDF2B297D04 | sha1: 84263829BBC2E4C030B8E5C9AF917C830E275ADF | sha256: 7A551684224EC52D2442CDF5FFA48A2300508AF8033175CAB469E0DD1975AFB9 | sha512: EC0DEDBEFD1B80B7C2C3BD7145F85353A0DF7318B2D2CF2825EF715D886E75A425E0FB9DDD5FA30D4D554DA2FE2FE2F3B5244DC264288DC86F5180AE9A0B5944
tools\_internal\PyQt6\QtWidgets.pyd
md5: D1FC9249F9633DDD6F65D914993D06B3 | sha1: A7BA3F43564D42313A5527C34A0FDF0185AA0067 | sha256: BB901B3335872D2033C4AF288C08B7E91010DC6B87F6F4E0F0264C9A9CDF6E71 | sha512: D426DC807BA6A4FB65272DF84F3FE3695DA04793B6FDBC443352FF0572B39CE7DF5B72A9A34472A4892D6B2EC078215839F63B5F04D25E9CBB4B307E8772C9C4
tools\_internal\PyQt6\sip.cp313-win_amd64.pyd
md5: 72F1682039BD75A7F58B269DC6B2AE6B | sha1: 5113880FF7C0EAD7CA7B6357B925CDED85FCCA0A | sha256: DB0C0D88943C250BFFCAE6E5103AF9693944C4A4A837EE69F6CE00E469264E30 | sha512: E8846269A5B14168CFFC101244F51C0AB07792791A434E0887151C4A64D6DAF9CD92071ED333DEA2757D7DBDC3B7B699E47BE839005B84380A084A9975AE017F
tools\_internal\python3.dll
md5: AD2C4784C3240063EEAA646FD59BE62C | sha1: 5EFAB563725781AB38A511E3F26E0406D5D46E8D | sha256: C1DE4BFE57DC4A5BE8C72C865D617DC39DFD8162FCD2CE1FAC9F401CF9EFB504 | sha512: C964D4289206D099310BD5299F71A32C643311E0E8445E35AE3179772136D0CA9B75F5271EAF31EFC75C055CD438799CEF836ED87797589629B0E9F247424676
tools\_internal\python313.dll
md5: 3AAD23292404A7038EB07CE5A6348256 | sha1: 35CAC5479699B28549EBE36C1D064BFB703F0857 | sha256: 78B1DD211C0E66A0603DF48DA2C9B67A915AB3258701B9285D3FAA255ED8DC25 | sha512: F5B6EF04E744D2C98C1EF9402D7A8CE5CDA3B008837CF2C37A8B6D0CD1B188CA46585A40B2DB7ACF019F67E6CED59EFF5BC86E1AAF48D3C3B62FECF37F3AEC6B
tools\_internal\pywin32_system32\pywintypes313.dll
md5: 2A87D04E9E7CBFF67E8EA4F6315C0EBB | sha1: CF5B2BB53B37087ECA18E509B8551ED5CB7575D9 | sha256: D011068781CFBA0955258505DBE7E5C7D3D0B955E7F7640D2F1019D425278087 | sha512: 2138E051AC116D3ABE11101C75F8BD8388D7FBA89B15E6F82DC35FD78BDD913ED8BA468769F68440CE7834825806281AA15F0023855E3B8248266414D60A4A44
tools\_internal\release_notes.txt
Version 2.6.0:
Addition of iconography to the GUI.
Migration to a new thread managing model to improve processing times.
Addition of support for the Xbox game launcher.
Refactoring of base code to cleanup and improve functional logic.
Remork to the whitelist logic to prevent spamming of the console with what games are whitelisted repeatedly.

Version 2.6.1:
Hotfix to fix folders being unclickable.

Version 2.6.2:
Addition of a toggle logger button to the GUI.
Coloured filtering for log events is now included.
Cleanup of the launcher icons to be more presentable.
Breakup of individual code components.
Inclusion of a "Reset path" toggle for launchers.
Inclusion of being able to view (these) release notes from inside the GUI.
Fixes to thread management shenanigans.
Bug fix to allow multiple reruns.

Version 2.6.3:
Addition of a logo.

Version 2.6.4:
Performance improvements for scanning directories.
Rewrite of scanning subdirectories.
There is now an output of the results in a box.
Removal of the full banner from the GUI.

Version 2.6.5:
Updates the DLSS files to DLSS 4.0.
Use at your own discretion :).

Version 2.6.6:
Bug fix for FG/RR DLL's being included in the skip for <2.0.0.

Version 2.6.7:
Updates to the DLL's to allow for profile K (refined version of profile J) to be the default for DLSS.
tools\_internal\select.pyd
md5: 62FE3761D24B53D98CC9B0CBBD0FEB7C | sha1: 317344C9EDF2FCFA2B9BC248A18F6E6ACEDAFFFB | sha256: 81F124B01A85882E362A42E94A13C0EFF2F4CCD72D461821DC5457A789554413 | sha512: A1D3DA17937087AF4E5980D908ED645D4EA1B5F3EBFAB5C572417DF064707CAE1372B331C7096CC8E2E041DB9315172806D3BC4BB425C6BB4D2FA55E00524881
tools\_internal\setuptools\_vendor\importlib_metadata-8.0.0.dist-info\INSTALLER
 
tools\_internal\setuptools\_vendor\importlib_metadata-8.0.0.dist-info\LICENSE
 
tools\_internal\setuptools\_vendor\importlib_metadata-8.0.0.dist-info\METADATA
tools\_internal\setuptools\_vendor\importlib_metadata-8.0.0.dist-info\RECORD
 
tools\_internal\setuptools\_vendor\importlib_metadata-8.0.0.dist-info\REQUESTED
 
tools\_internal\setuptools\_vendor\importlib_metadata-8.0.0.dist-info\top_level.txt
importlib_metadata
tools\_internal\setuptools\_vendor\importlib_metadata-8.0.0.dist-info\WHEEL
 
tools\_internal\setuptools\_vendor\wheel-0.43.0.dist-info\entry_points.txt
[console_scripts]
wheel=wheel.cli:main

[distutils.commands]
bdist_wheel=wheel.bdist_wheel:bdist_wheel

tools\_internal\setuptools\_vendor\wheel-0.43.0.dist-info\INSTALLER
 
tools\_internal\setuptools\_vendor\wheel-0.43.0.dist-info\LICENSE.txt
MIT License

Copyright (c) 2012 Daniel Holth <[email protected]> and contributors

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
tools\_internal\setuptools\_vendor\wheel-0.43.0.dist-info\METADATA
tools\_internal\setuptools\_vendor\wheel-0.43.0.dist-info\RECORD
 
tools\_internal\setuptools\_vendor\wheel-0.43.0.dist-info\REQUESTED
 
tools\_internal\setuptools\_vendor\wheel-0.43.0.dist-info\WHEEL
 
tools\_internal\ucrtbase.dll
md5: 286B308DF8012A5DFC4276FB16DD9CCC | sha1: 8AE9DF813B281C2BD7A81DE1E4E9CEF8934A9120 | sha256: 2E5FB14B7BF8540278F3614A12F0226E56A7CC9E64B81CBD976C6FCF2F71CBFB | sha512: 24166CC1477CDE129A9AB5B71075A6D935EB6EEBCAE9B39C0A106C5394DED31AF3D93F6DEA147120243F7790D0A0C625A690FD76177DDDAB2D2685105C3EB7B2
tools\_internal\unicodedata.pyd
md5: 43B8B61DEBBC6DD93124A00DDD922D8C | sha1: 5DEE63D250AC6233AAC7E462EEE65C5326224F01 | sha256: 3F462EE6E7743A87E5791181936539642E3761C55DE3DE980A125F91FE21F123 | sha512: DD4791045CF887E6722FEAE4442C38E641F19EC994A8EAF7667E9DF9EA84378D6D718CAF3390F92443F6BBF39840C150121BB6FA896C4BADD3F78F1FFE4DE19D
tools\_internal\VCRUNTIME140.dll
md5: 862F820C3251E4CA6FC0AC00E4092239 | sha1: EF96D84B253041B090C243594F90938E9A487A9A | sha256: 36585912E5EAF83BA9FEA0631534F690CCDC2D7BA91537166FE53E56C221E153 | sha512: 2F8A0F11BCCC3A8CB99637DEEDA0158240DF0885A230F38BB7F21257C659F05646C6B61E993F87E0877F6BA06B347DDD1FC45D5C44BC4E309EF75ED882B82E4E
tools\_internal\VCRUNTIME140_1.dll
md5: 68156F41AE9A04D89BB6625A5CD222D4 | sha1: 3BE29D5C53808186EBA3A024BE377EE6F267C983 | sha256: 82A2F9AE1E6146AE3CB0F4BC5A62B7227E0384209D9B1AEF86BBCC105912F7CD | sha512: F7BF8AD7CD8B450050310952C56F6A20B378A972C822CCC253EF3D7381B56FFB3CA6CE3323BEA9872674ED1C02017F78AB31E9EB9927FC6B3CBA957C247E5D57
tools\_internal\win32\win32api.pyd
md5: C5067F04B506B09E48D4D07470E5A182 | sha1: 20435C1A092141CE67E943C95E5CF522762ACD91 | sha256: E19294BC2C145A9D87D4A2D8412830C8FF4C8C1B9AD005BD68ABD4B566AF1887 | sha512: 56F08A5EB927921DED50E92EA972253E68C1216DAA48871B3AA9ED62DB5712E665DFDA406C73E9F33736B61ED1F0CD016E6B4FFEE0237781FB98EEB63672F81E
tools\_internal\_asyncio.pyd
md5: 142E957AE9FE9DD8514E1781C9A35C2B | sha1: 66D587F8B3A9F8CF237FC682C6E6D3D0929F1DF9 | sha256: 4C6D6690E91974804C1EAF77827EA63882711689BAFF0718A246796FF40B2A23 | sha512: 874A827A6183BFE9898C80C25DB4336EB58273A0EC701BC5F497364AFE3084D6634BF6DB7F9DC02EF593C6A751E678BE419E9AF050BD51C4BBB89D98F53C5F0B
tools\_internal\_bz2.pyd
md5: C17DCB7FC227601471A641EC90E6237F | sha1: C93A8C2430E844F40F1D9C880AA74612409FFBB9 | sha256: 55894B2B98D01F37B9A8CF4DAF926D0161FF23C2FB31C56F9DBBAC3A61932712 | sha512: 38851CBD234A51394673A7514110EB43037B4E19D2A6FB79471CC7D01DBCF2695E70DF4BA2727C69F1FED56FC7980E3CA37FDDFF73CC3294A2EA44FACDEB0FA9
tools\_internal\_ctypes.pyd
md5: 2BD5DABBB35398A506E3406BC01EBA26 | sha1: AF3AB9D8467E25367D03CB7479A3E4324917F8D0 | sha256: 5C4C489AC052795C27AF063C96BC4DB5AB250144D4839050CFA9BB3836B87C32 | sha512: C07860D86AE0D900E44945DA77E3B620005667304C0715985F06000F3D410FFFB7E38E1BC84E4E6D24889D46B9DAC6BF18861C95B2B09E760012EDC5406B3838
tools\_internal\_decimal.pyd
md5: AD4324E5CC794D626FFCCDA544A5A833 | sha1: EF925E000383B6CAD9361430FC38264540D434A5 | sha256: 040F361F63204B55C17A100C260C7DDFADD00866CC055FBD641B83A6747547D5 | sha512: 0A002B79418242112600B9246DA66A5C04651AECB2E245F0220B2544D7B7DF67A20139F45DDF2D4E7759CE8CC3D6B4BE7F98B0A221C756449EB1B6D7AF602325
tools\_internal\_elementtree.pyd
md5: 422E303EF77E10DCA60C9C2634FD62C1 | sha1: E849F3E362F220E5C2445342BAE86B3A9A2FD21C | sha256: CE0991AFD99C15F3C07388EABEE461B39BD2738F2CB1DF4BEBFC330A32C5B5A9 | sha512: BCCEF1DA4DE68A22CDF1C8F79E209A476AA9196593FD533F3071CB45C74DDA2C3B6275183D00B39EADBCFAB1AA432DF44FD9C4F0B3F67574FCAECFD9ECFD5056
tools\_internal\_hashlib.pyd
md5: 422E214CA76421E794B99F99A374B077 | sha1: 58B24448AB889948303CDEFE28A7C697687B7EBC | sha256: 78223AEF72777EFC93C739F5308A3FC5DE28B7D10E6975B8947552A62592772B | sha512: 03FCCCC5A300CC029BEF06C601915FA38604D955995B127B5B121CB55FB81752A8A1EEC4B1B263BA12C51538080335DABAEF9E2B8259B4BF02AF84A680552FA0
tools\_internal\_lzma.pyd
md5: 66A9028EFD1BB12047DAFCE391FD6198 | sha1: E0B61CE28EA940F1F0D5247D40ABE61AE2B91293 | sha256: E44DEA262A24DF69FD9B50B08D09AE6F8B051137CE0834640C977091A6F9FCA8 | sha512: 3C2A4E2539933CBEB1D0B3C8EF14F0563675FD53B6EF487C7A5371DFE2EE1932255F91DB598A61AAADACD8DC2FE2486A91F586542C52DFC054B22AD843831D1E
tools\_internal\_multiprocessing.pyd
md5: 22D20BD3946419ECF0882315AE1F96DE | sha1: F3C07BEF75FA372A6905E971CA8350D1E3E48058 | sha256: 9DA721822A592F8C4E9A96EBAA4517C45768D7737582E0E5B933066F453A2E5E | sha512: A3BEC1F99240B9E9D823405EECC1C511C46F11C7D844229A0DAD7E23EDB69DF365874C184FE9B2637F12A94132E44ACECC3A434810D0FF5C819F8207F1DDDE9F
tools\_internal\_overlapped.pyd
md5: 4DF3728D404E0B1607A80B32C6C93BCC | sha1: D6EBD687DE4D5FD8037F0775D6EA88B84F6A8287 | sha256: C8A0E2C0D7F82CEDB839D2C0B827CF139113FAA4ABA05F2345C80E2CF3335B8A | sha512: F9F51AC1F82E2FA799249336A927A84B0A44055ADA0A136E318D9073633C2595445A933FBC74B0B3C16CBAD6C253D1DF76CAD031389D89DAF9A789DE1526E265
tools\_internal\_queue.pyd
md5: 955B197C38EA5BD537CE9C7CB2109802 | sha1: 8FEFFCB11740DDAFC4479FC008CC06C6B570A8BC | sha256: 73CADE82EE139459FE5841E5631274FC9CAF7F579418B613F278125435653539 | sha512: CAB0D8D10FB3BFF72D20B287901CCD9BE685796142CD2E45E4712CD6F4551DEC69180490C2FDFAD262C6927A3C7F4FEFE68187F64C066731FE17012F78A0ED69
tools\_internal\_socket.pyd
md5: ABF998769F3CBA685E90FA06E0EC8326 | sha1: DAA66047CF22B6BE608127F8824E59B30C9026BF | sha256: 62D0493CED6CA33E2FD8141649DD9889C23B2E9AFC5FDF56EDB4F888C88FB823 | sha512: 08C6B3573C596A15ACCF4936533567415198A0DAAB5B6E9824B820FD1F078233BBC3791FDE6971489E70155F7C33C1242B0B0A3A17FE2EC95B9FADAE555ED483
tools\_internal\_ssl.pyd
md5: CF541CC288AC0BEC9B682A2E0011D1FF | sha1: EF0DD009FDAD14B3F6063619112DCDFAFB17186D | sha256: E94F0195363C5C9BABFC4C17EC6FB1AA8BBABF59E377DB66CE6A79C4C58BBD07 | sha512: F97E7FC644356BEBE7E3DEAA46B7DE61118B13AF99C9E91D0FBCBE3CAEA0C941265BCB28FEE31A22FC3031C6428517C5202C1425654F3C2CD234979C9E3C04B8
tools\_internal\_uuid.pyd
md5: B5F2D9353F758E1A60E67DAC33DEBDD2 | sha1: EDAE6378D70B76846329FA609483DE89531BCF16 | sha256: CDE836EF0BDE1C15C1C3750DE54B50D2285864C512ABBFC9E2C94F0FF5AA5CA2 | sha512: 9D780A8EC760C6BAE3B53079C9A0670C7CBF2AF6AABABDA0234EE71C5E0546B501CBE9666D973EAA28FB7FB7285814ECFECE98D20CF4A86D3AEA9A61A8120397
tools\_internal\_wmi.pyd
md5: C629CE084FC76AC60B7A77479CB2225C | sha1: FE80955F217162CE9D4910202BBE30F7601D254A | sha256: AFAD80F9E62A57814779CF3E48352B583C1A0697B11A23CC9DB3F4E43F7F8664 | sha512: 9863767981508F458C61553E5A50B6C5D70956676FEE92E15B5AB08B1770BA0F640392FA12FEDDD6AB1EAC5A418F3F8CD057C608E33653A2825CA36EDDED78B6

Log in or click on link to see number of positives.

In cases where actual malware is found, the packages are subject to removal. Software sometimes has false positives. Moderators do not necessarily validate the safety of the underlying software, only that a package retrieves software from the official distribution point and/or validate embedded software against official distribution point (where distribution rights allow redistribution).

Chocolatey Pro provides runtime protection from possible malware.

Add to Builder Version Downloads Last Updated Status
DLSS Updater 2.6.6 9 Thursday, January 30, 2025 Approved
DLSS Updater 2.6.5 13 Saturday, January 25, 2025 Approved
DLSS Updater 2.6.4 142 Monday, January 13, 2025 Approved
DLSS Updater 2.6.3 12 Thursday, January 9, 2025 Approved
DLSS Updater 2.6.2 44 Friday, January 3, 2025 Approved
DLSS Updater 2.6.1 27 Saturday, December 28, 2024 Approved
DLSS Updater 2.5.2 49 Thursday, December 19, 2024 Approved
DLSS Updater 2.5.1 44 Saturday, December 14, 2024 Approved
DLSS Updater 2.2.6 25 Thursday, November 14, 2024 Approved
DLSS Updater 2.2.3 155 Thursday, September 26, 2024 Approved
Discussion for the DLSS Updater Package

Ground Rules:

  • This discussion is only about DLSS Updater and the DLSS Updater package. If you have feedback for Chocolatey, please contact the Google Group.
  • This discussion will carry over multiple versions. If you have a comment about a particular version, please note that in your comments.
  • The maintainers of this Chocolatey Package will be notified about new comments that are posted to this Disqus thread, however, it is NOT a guarantee that you will get a response. If you do not hear back from the maintainers after posting a message below, please follow up by using the link on the left side of this page or follow this link to contact maintainers. If you still hear nothing back, please follow the package triage process.
  • Tell us what you love about the package or DLSS Updater, or tell us what needs improvement.
  • Share your experiences with the package, or extra configuration or gotchas that you've found.
  • If you use a url, the comment will be flagged for moderation until you've been whitelisted. Disqus moderated comments are approved on a weekly schedule if not sooner. It could take between 1-5 days for your comment to show up.
comments powered by Disqus