Downloads:
1,018
Downloads of v 2.7.0:
37
Last Update:
05 Apr 2025
Package Maintainer(s):
Software Author(s):
- Deco
Tags:
dlss nvidia gaming update-tool admin- Software Specific:
- Software Site
- Software Source
- Software License
- Software Docs
- Software Issues
- Package Specific:
- Package Source
- Package outdated?
- Package broken?
- Contact Maintainers
- Contact Site Admins
- Software Vendor?
- Report Abuse
- Download
DLSS Updater
This is not the latest version of DLSS Updater available.
- 1
- 2
- 3
2.7.0 | Updated: 05 Apr 2025
- Software Specific:
- Software Site
- Software Source
- Software License
- Software Docs
- Software Issues
- Package Specific:
- Package Source
- Package outdated?
- Package broken?
- Contact Maintainers
- Contact Site Admins
- Software Vendor?
- Report Abuse
- Download
Downloads:
1,018
Downloads of v 2.7.0:
37
Maintainer(s):
Software Author(s):
- Deco
DLSS Updater 2.7.0
This is not the latest version of DLSS Updater available.
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
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:
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
Option 1: Cached Package (Unreliable, Requires Internet - Same As Community)-
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
-
Open Source
-
Download the package:
Download - Follow manual internalization instructions
-
-
Package Internalizer (C4B)
-
Run: (additional options)
choco download dlss-updater --internalize --version=2.7.0 --source=https://community.chocolatey.org/api/v2/
-
For package and dependencies run:
choco push --source="'INTERNAL REPO URL'"
- Automate package internalization
-
Run: (additional options)
3. Copy Your Script
choco upgrade dlss-updater -y --source="'INTERNAL REPO URL'" --version="'2.7.0'" [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'" --version="'2.7.0'"
$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.7.0'
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.7.0'
end
See docs at https://docs.chef.io/resource_chocolatey_package.html.
cChocoPackageInstaller dlss-updater
{
Name = "dlss-updater"
Version = "2.7.0"
Source = "INTERNAL REPO URL"
}
Requires cChoco DSC Resource. See docs at https://github.com/chocolatey/cChoco.
package { 'dlss-updater':
ensure => '2.7.0',
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.
This package was approved as a trusted package on 07 Apr 2025.
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.
md5: C754FEA40ECFC2C0FAB9F39F778D7ECF | sha1: FED5A26B748B41A78BD0A6B1EFAEF17A1F3ED0BA | sha256: 9AB6BD24B88732E85EA7005621EEEA610172118DE3ACDC3FC6112DE9A52B0C6B | sha512: BF42393AB609CA13FB4089015DC62954FC123DAF754EDB426A81DBDF80DBEAFCBBFF198446F78CAB1AF2B303CB5C5111F6EAE7B68CB3F7D8566CEF12F4C40011
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: 9AB6BD24B88732E85EA7005621EEEA610172118DE3ACDC3FC6112DE9A52B0C6B
md5: 9F746F4F7D845F063FEA3C37DCEBC27C | sha1: 24D00523770127A5705FCC2A165731723DF36312 | sha256: 88ACE577A9C51061CB7D1A36BABBBEFA48212FADC838FFDE98FDFFF60DE18386 | sha512: 306952418B095E5CF139372A7E684062D05B2209E41D74798A20D7819EFEB41D9A53DC864CB62CC927A98DF45F7365F32B72EC9B17BA1AEE63E2BF4E1D61A6E4
md5: 8F8EB9CB9E78E3A611BC8ACAEC4399CB | sha1: 237EEE6E6E0705C4BE7B0EF716B6A4136BF4E8A8 | sha256: 1BD81DFD19204B44662510D9054852FB77C9F25C1088D647881C9B976CC16818 | sha512: 5B10404CDC29E9FC612A0111B0B22F41D78E9A694631F48F186BDDE940C477C88F202377E887B05D914108B9BE531E6790F8F56E6F03273AB964209D83A60596
md5: 226A5983AE2CBBF0C1BDA85D65948ABC | sha1: D0F131DCBA0F0717C5DEA4A9CA7F2E2ECF0AD1C3 | sha256: 591358EB4D1531E9563EE0813E4301C552CE364C912CE684D16576EABF195DC3 | sha512: A1E6671091BD5B2F83BFAA8FCF47093026E354563F84559BD2B57D6E9FA1671EEA27B4ED8493E9FDF4BDE814074DC669DE047B4272B2D14B4F928D25C4BE819D
md5: C2F8C03ECCE9941492BFBE4B82F7D2D5 | sha1: 909C66C6DFEA5E0C74D3892D980918251BB08632 | sha256: D56CE7B1CD76108AD6C137326EC694A14C99D48C3D7B0ACE8C3FF4D9BCEE3CE8 | sha512: 7C6C85E390BBE903265574E0E7A074DA2CE30D9376D7A91A121A3E0B1A8B0FFFD5579F404D91836525D4400D2760CB74C9CB448F8C5AE9713385329612B074CF
md5: B5E2760C5A46DBEB8AE18C75F335707E | sha1: E71DB44FC0E0C125DE90A9A87CCB1461E72A9030 | sha256: 91D249D7BC0E38EF6BCB17158B1FDC6DD8888DC086615C9B8B750B87E52A5FB3 | sha512: C3400772D501C5356F873D96B95DC33428A34B6FCAAD83234B6782B5F4BF087121E4FD84885B1ABAB202066DA98EB424F93DD2EED19A0E2A9F6FF4A5CFD1E4F3
md5: 050A30A687E7A2FA6F086A0DB89AA131 | sha1: 1484322CAAF0D71CBB873A2B87BDD8D456DA1A3B | sha256: FC9D86CEC621383EAB636EBC87DDD3F5C19A3CB2A33D97BE112C051D0B275429 | sha512: 07A15AA3B0830F857B9B9FFEB57B6593AE40847A146C5041D38BE9CE3410F58CAA091A7D5671CC1BC7285B51D4547E3004CF0E634AE51FE3DA0051E54D8759E1
md5: 9F45A47EBFD9D0629F4935764243DD5A | sha1: 86A4A0EA205E31FB73F3BFCCE24945BD6BEA06C7 | sha256: 1CA895ABA4E7435563A6B43E85EBA67A0F8C74AA6A6A94D0FC48FA35535E2585 | sha512: 8C1CDCAD557BFF1685A633D181FCF14EC512D322CAEAEB9C937DA8794C74694FE93528FC9578CB75098F50A2489ED4A5DEDF8C8C2AC93EEB9C8F50E3DD690D5F
md5: CC228FF8D86B608E73026B1E9960B2F8 | sha1: CEF0705AEE1E8702589524879A49E859505D6FE0 | sha256: 4CADBC0C39DA7C6722206FDCEBD670ABE5B8D261E7B041DD94F9397A89D1990D | sha512: 17ABD9E0EC20B7EB686E3C0F41B043D0742AB7F9501A423B2D2922D44AF660379792D1CC6221EFFBD7E856575D5BABF72657AE9127C87CC5CF678BD2CEB1228F
md5: E368A236F5676A3DA44E76870CD691C9 | sha1: E4F1D2C6F714A47F0DC29021855C632EF98B0A74 | sha256: 93C624B366BA16C643FC8933070A26F03B073AD0CF7F80173266D67536C61989 | sha512: F5126498A8B65AB20AFAAF6B0F179AB5286810384D44638C35F3779F37E288A51C28BED3C3F8125D51FEB2A0909329F3B21273CB33B3C30728B87318480A9EF8
md5: 416AA8314222DB6CBB3760856BE13D46 | sha1: 5F28FE2D565378C033EF8EEA874BC38F4B205327 | sha256: 39095F59C41D76EC81BB2723D646FDE4C148E7CC3402F4980D2ADE95CB9C84F9 | sha512: B16ED31DC3343CAEA47C771326810C040A082E0AB65D9AE69946498CEB6AE0DEE0A570DBCD88090668A100B952C1FF88BADE148811B913C90931AA0E657CD808
md5: 344A09B4BE069F86356A89482C156647 | sha1: 2506FFEB157CB531195DD04D11D07C16E4429530 | sha256: 8F105771B236DBCB859DE271F0A6822CE1CB79C36988DD42C9E3F6F55C5F7EB9 | sha512: 4C1E616443576DC83200A4F98D122065926F23212B6647B601470806151FF15EA44996364674821AFEC492B29BA868F188A9D6119B1E1D378A268F1584CA5B29
md5: 86023497FA48CA2C7705D3F90B76EBC5 | sha1: 835215D7954E57D33D9B34D8850E8DC82F6D09E8 | sha256: 53B25E753CA785BF8B695D89DDE5818A318890211DC992A89146F16658F0B606 | sha512: 8F8370F4C0B27779D18529164FA40CBFDDAFA81A4300D9273713B13428D0367D50583271EA388D43C1A96FED5893448CD14711D5312DA9DFA09B9893DF333186
md5: 0C1CC0A54D4B38885E1B250B40A34A84 | sha1: 24400F712BBE1DD260ED407D1EB24C35DCB2ECAC | sha256: A9B13A1CD1B8C19B0C6B4AFCD5BB0DD29C0E2288231AC9E6DB8510094CE68BA6 | sha512: 71674E7ED8650CAC26B6F11A05BFC12BD7332588D21CF81D827C1D22DF5730A13C1E6B3BA797573BB05B3138F8D46091402E63C059650C7E33208D50973DDE39
md5: 5FBCB20D99E463259B4F15429010B9CD | sha1: B16770F8BB53DC2BAFCB309824D6FA7B57044D8A | sha256: 7F39BA298B41E4963047341288CAB36B6A241835EE11BA4AD70F44DACD40906C | sha512: 7BA1AC34B3ECFBFB8252F5875BE381D8EF823B50DFE0E070222175EE51191F5EE6D541EEEDD1445ED603A23D200CE9CE15914C8ED3FAFE7E7F3591F51F896C58
md5: 5241DF2E95E31E73CCFD6357AD309DF0 | sha1: 2644CC5E86DFAD1AD2140181AB2CA79725F95411 | sha256: 6EE44DD0D8510DC024C9F7C79B1B9FA88C987B26B6BEB6653DDD11751C34E5DC | sha512: 52CCCD1DD237E764E34996C0C5F7A759A7F0EFF29B61BEFEAF96A16D80DF2BA9EE2C3615F875153198A145D68F275AEA6D02187E6EEE5A129E3E2AB81AACEB16
md5: 8D285430E8BDA6D5C9B683579ADCB180 | sha1: 619DBBCFF06C659E3FC48F03917A4DADBFC1C275 | sha256: 0512A35316EC9180437F86696A84C5C06A7E4E82E050055A656E5BF9FCA206F9 | sha512: 38405DD85DD62F843ABB55ACEA1B64D7D63BB601445BF1B32078CDE5BBEF4861DD99F26659281FE2AEA86F58CFB1725D8C63D91FB539DCBF5D98CDBE783337FC
md5: 4A28CA64F44B91F43945EE3971E0996A | sha1: 45B3D8584C58E8D6AE507FDBD772FEEB1886C8B0 | sha256: C05F1FFFE3B5A2738EA54CE9485CCA026FB9635F982626FBA1E1DCC531897273 | sha512: 862A0428F08D447CD1EE0431969E0FBCB182F4C46418C26D26FA33E586E686D9C093C1CA5781F544CE9276195CE973850719636E39E465F059607F455ECFDD93
md5: 7FD4A71085783CCFE9C289C07BCF9B04 | sha1: BB6FFDB5C069DBBA06998DC877D24F72DAD6298D | sha256: C4ECA98C3C67B6395D5B005B00AC1EB0318B86B23AA71035A44C2B1602BEFBA9 | sha512: A96C5B90B8384B239BE111D90CAA3B947651AD73382AB9E5DBE4A4B6AD30921876545331D37C8D5A8F669E39D71BF60983C4BA39C479E23015C2F7579C5E55CD
md5: C123F2C161884FBFF4F00EF1E1391266 | sha1: 7DB3055DA53916BEA2B85B159491A0772FB620CE | sha256: 5CCB89E93D67BC3288D4E84649C5346E66E15E3D7CD65D989DAF3F4CB584BE9A | sha512: DAC5616320B9052254B5687959E67126C4A938E79173D8245675A9651674384C36CC856F996EF88AE621EC67AFC6616626657585D92BB5D14602A7CC9FC0F669
md5: 385F562BDC391CCD4F81ACA3719F3236 | sha1: F6633E1DAC227BA3CD14D004748EF0C1C4135E67 | sha256: 4AD565A8BA3EF0EA8AB87221AD11F83EE0BC844CE236607958406663B407333E | sha512: B72ED1A02D4A02791CA5490B35F7E2CB6CB988E4899EDA78134A34FB28964EA573D3289B69D5DB1AAC2289D1F24FD0A432B8187F7AE8147656D38691AE923F27
md5: 7A629293EEB0BCA5F9BDEE8ADE477C54 | sha1: A25BF8BAC4FBFD9216EA827E71344BA07B1D463B | sha256: 7809160932F44E59B021699F5BC68799EB7293EE1FA926D6FCCA3C3445302E61 | sha512: 1C58C547D1FE9B54DDF07E5407EDAF3375C6425CA357AA81D09C76A001376C43487476A6F18C891065AB99680501B0F43A16A10ED8E0D5E87B9A9542098F45FE
md5: 3C5C7A3130B075B2DEF5C413C127173F | sha1: F3D2B8AD93F3DC99C8410D34C871AEC56C52E317 | sha256: 9DC1E91E71C7C054854BD1487CB4E6946D82C9F463430F1C4E8D1471005172B1 | sha512: 46A52631E3DD49B0AE10AFBDF50A08D6D6575F3093B3921B2FA744704E2D317F8B10A6D48AD7F922A7843731782521773032A6CC04833B00BD85E404C168FFE4
md5: 28005B20FBEF6E1DB10912D0FDD6471C | sha1: 47B83697677E08E4EBCFF6FC41ECA7ECE120CC17 | sha256: 60FC31D2A0C634412F529DBA76AF3B9BF991352877C6DAE528186D3935704CFD | sha512: 45D6F860D7F7AEFAA7A0A3B4B21B5C3234F442E39D6259E0A9E2083890533C275F07DDDA93FDDC7445928A55475B83C63253D3B08E41E5576F9029B205DFB36A
md5: 436EA0237ED040513EC887046418FAAA | sha1: 44BAFBBDB1B97D86505E16B8A5FCB42B2B771F91 | sha256: 3A72B4F29F39A265D32AD12F0CE15DBF60129C840E10D84D427829EDE45E78AD | sha512: 9F0DBFB538C05383AE9ABFE95E55740530ECC12C1890D8862DEACBC84212BE0740D82AFC9E81D529125221E00B2286CAE0D4B3CA8DD3A6C57774D59F37933692
md5: 8F107A7BC018227B181A0E7E76E9CA39 | sha1: EF57E24F29D2B1DEEACEFD82171873B971A3F606 | sha256: EFC1E4460984A73CF47A3DEF033AF1C8F3B1DBC1A56CD27781D3AACF3E3330CB | sha512: D8D8250AAF93FA99E9D1E4286B32579DE0029C83867A787C0A765505A0F8CBD2DD076BB324509D5C4867423BC7DC8F00C8B8458E08E8CBFA8DD731D03DD1AE3F
md5: B65BF5EF316880FD8D21E1B34EB5C8A9 | sha1: 3AB4674CB5C76E261FE042D6D0DA8A20BFCBCBAE | sha256: B203D862DDEF1DD62BF623FC866C7F7A9C317C1C2AE30D1F52CB41F955B5698E | sha512: 4AF3B0EF9A813CE1A93A35DD6869817910AE4B628F374477F60EA1831D2CC1AAE7908262672E11954A4953BDFF22BCC5FE23B4A736788E8E5EF4F8AC30EB24F8
md5: FC9FC5F308FFC2D2D71814DF8E2AE107 | sha1: 24D7477F2A7DC2610EB701ED683108CD57ECA966 | sha256: 2703635D835396AFD0F138D7C73751AFE7E33A24F4225D08C1690B0A371932C0 | sha512: 490FA6DC846E11C94CFE2F80A781C1BD1943CDDD861D8907DE8F05D9DC7A6364A777C6988C58059E435AC7E5D523218A597B2E9C69C9C34C50D82CAC4400FE01
md5: 43D8D2FB8801C5BD90D9482DDF3EA356 | sha1: D582B55CD58531E726141C63BA9910FF185D72E0 | sha256: 33F4FDDC181066FCE06B2227BDED813F95E94ED1F3D785E982C6B6B56C510C57 | sha512: 0E073381A340DB3F95165DBCCEB8DFBF1ED1B4343E860446032400A7B321B7922C42EE5D9A881E28E69A3F55D56D63663ADB9BB5ABB69C5306EFBF116CC5E456
md5: 3C58A804B90A0782E80BBBF6C6B6F167 | sha1: B333143E0F6E508B51D27ADF7872B586FA54C794 | sha256: 6EDA016742A6171205A387A14B3C0B331841567740376F56768F8C151724207D | sha512: 773F8DEDED48B34BABE24D955A501F4F357C20125AFFB6EADE36CE6A7ACD380906713C366318F79D627747E636D156875C216FFFAC26DBA25373BBC1C820DA76
md5: 5794B8E183EB547AADD5FAF30A8C4DD2 | sha1: 5B1ED8A9DA14D8ECC4209662809727931AA49307 | sha256: B762061B688AAE679AFE788904D2C9970F74A7DAC98F3B42463D08F25E483D3F | sha512: 3E896854E5DD957AB2B88C82FBAF2EAA03729BAB30FD8518BD999081F4DA9000D9B22894B324E5930DF161C7ADAEC3FC87FD00DE60DCDA34876007AEA4A2FD31
md5: 3560176D0CDBE2F5D33F543348E0A027 | sha1: 1E35A1F7793FC3899927835491F28FE5B903EDCD | sha256: EBB2AE5535A64F65DAEAB8235585114FC9DD2CF1A49F5852D446250B998B6AE4 | sha512: 8AB24C8C9FE8331F21BE96818C5FA69AE5578EB742C4504596310BB0DB7C4C087D350FA47A13ED9FF2E051BB62AC5581DE082D0177923D24FEE6B140AFECF50B
md5: E93C7F013493B12AD40229B19DB02CE6 | sha1: EF878BFBFD2F8328BBB8CFF1AA29A39E624A8503 | sha256: 17D63275D00BDD8670422B95BD264C532998E0A1B041079E54FCE4B6B7A55819 | sha512: 2F4A25EA4062840BEA10442CAD665A72ABBCE747307AD9CE7B3BB89EAF7DCC28F1E9396749576BE304FD793690DDC445653613440442695E72B761EACACB6020
md5: 47555752931CECF90E796499B62EC729 | sha1: 217B171764FBA5E91190D1F8A36FECCB3F6D4585 | sha256: 9A9E2A65A281644E368D0F272B95BA5F6B445D1C35910D06056C5EBEB77402DB | sha512: A68009F0306D4D8E70951978D2C184EB80FBEC98C6DB0997BD7B0B503DD63019363CFEF68A9ADBFB568C0A552B774FBDBEB1BCF45F211A6A3224B49E85A5619C
md5: 527BBBFDED529EA77EE798D94CE0F243 | sha1: 647F8C89EB4DB3CF3656292B3DE984B32C6E02A5 | sha256: BAB9AC3EC83E380AE51E4295EF3BF2C738627812D3A49D1E713661ABBC8DC57A | sha512: C1ED69E15AB19084390CF9D1CEAB791758AC4DDD688169F3B814B0E4CF1FC3B6BA17651E35B25DCDC601A8A64821D58933D52A5E939942FA134DFD04FCA04C8B
md5: 09796DAB12CBBD920F632AEB89820193 | sha1: 7D81C0E5537B6D8B79AF0C28CD102E064027C78D | sha256: BD14C67EA28E21D6257AD780A37122C9B5773F69E693F5DB6BFFAEE4D839526E | sha512: 09A6175DCCBBD18A62209E156089F1167DFB8040C97C8C2C14724CE2A8FBE6CE039D7FE04FB8BD60092427BEB7FDD8E7127D611F006FFF1CF2A1AD75E9E5EF3A
md5: AA9624CB27CC50A3FBBD3B223A617B1C | sha1: 797AEA1C5CEDD1125276BFC5DCD7A3FB8C6355AA | sha256: 606D66D82DB562EA7979179D06486A0F94D079941D26B80A1E2C49D29959DF6F | sha512: 024975E6787F7A6B0AB6E4B02AD33901F8473B97DC73D4F03B7A116B24AC74150C0C48990EA7A4FB750F9FE728DAFED172796743F802E70F2150EEFCF70FE96A
md5: 9D6925407136753E8EB8234D59FA3F1F | sha1: 62631B7007D394FB4D406EA686B291FFF9E486CD | sha256: F6156B1020380EC4F0E48577EBEDAAEF5FB1AB1F337D8B4E72E6A33A7567A9CC | sha512: AB04DE62524E465810CD0EE81E85018863E276D49861E67A920667AF802E94869B816B47A6E3C4738179A7A7D726D44BBBA6E47D9097363A63EAFF51CD56DE8A
md5: BBAA58E9E1ABDF7D8C4C69652D29D789 | sha1: 38AEF13ABC14502354E8C5C3C37B97A8E2E5FDCF | sha256: C5902934D026D7E15FBE9917D474F3322846A41A25E66F4B2B1F758801879F4B | sha512: 7882A8E1E1EA7E217F70FF9DF27D36709B4BE23588909EF002F3EB1B9A7D3EEA2591A8524AF2C83448DDFFF0911658517C6989683245C54678583F359A78B0AD
md5: EF37235FC43157A4C93241D5E49E304B | sha1: D4DE26B36812C2DDCCD1618B4D7AC02AD1B42273 | sha256: A9C5A153D8C0286F9B41A2B1C65854AD9E6471B8755B7DE87BAE4470E60BCAB6 | sha512: C0857760D5D069BEEB1EB1737F4160530910331BF6047022836CF58137BD28C2A966A8760A681859F57EBD810FD424CE231402EDDDE1316EAEF7B6F9F773AFBB
md5: 639B1FB35CB61BA633EB1791B750631F | sha1: 392A6925009F5FB02A4C122C9CE31D82B9059628 | sha256: 25B8F83A7767211B11132775A0E27A45AA4EC8AB4E6572599F9C172AE3606B40 | sha512: DEF547EF66673862CEA9BB13C433EDCE24A3075C328D9B3B9452F2F01F2F4243DAAB38C0F8571C52D601BC4AECAAA0682DBEBF6BE41CAE345787A719063EBF58
md5: FCCCE207A34C947F01D3F23A7DD09569 | sha1: 75F722801C77285DB98A08AF763252A0255E99E2 | sha256: 7C7F6393F06DE11750ADB09CC5698AE55CD9FB27B2E51E207286FEB1B5B2B156 | sha512: D3D923F133594EB4325F4A6E5ED46FCC348A7C0F310F14EAA38C6FAD070BA637BDB4A77200FEB231114E111D07A86595A6130291028CDE3A284D9F847EC38AD4
md5: 708A5BC205384633A7B6674EECC7F0F0 | sha1: 01603A7826029293236C67FCE02ACE8D392A0514 | sha256: D8BA5F17B9FFCBF3AEAF3FA1DA226832D2FA90F81ACCE0CD669464E76CE434AC | sha512: 8638845326AB6543338BAA7A644AF8BE33A123E1FC9DA2037158BE7C8D165691CCD06CB3FF73696A30B8801EAB030E81F93DB81216BB3B7E83A320A0DF5AF270
md5: 2DFF03F3FBE4F17109A5BC570E554667 | sha1: 99CA4BDB764EF2332981C9B0667C959A478F1574 | sha256: 5E7C1D8F96758470DA6D177670EB9384ECD8FE4410DD3CAA57CD003721E31038 | sha512: 2F549BB0C3162C362EF6224838654FBE8CC7B170EA79CAB0C69B2369AA8C63E74C90CF43AF8DFF933B611D400F2BAC5AFDFB01D021B345584DAE37A344034796
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])
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.1.0",
"nvngx_dlssd.dll": "310.2.1.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()
DLL_TYPE_MAP = {
"nvngx_dlss.dll": "DLSS DLL",
"nvngx_dlssg.dll": "DLSS Frame Generation DLL",
"nvngx_dlssd.dll": "DLSS Ray Reconstruction DLL",
}
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()
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")
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;
}
"""
)
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
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
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})")
__version__ = "2.6.8"
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
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",
]
md5: 3A875F45C315D09E5F4548CC9288F178 | sha1: 064709DA803D9A796C2E4AC17B5F904522C4F646 | sha256: 4E85CDBE0896AAB5F12C29F0B66AE7E5D9622CFADAC37AA9852ACBA8E4861F5A | sha512: 9628969F053F9DA54D84422BF8E0915EDC7129379AA49B4D12969628E7599BE256D1FE3EDD18AAE32C7A837C82DEE30E8C28EDD8C8246B240F76CF2103A12980
md5: E5311D6C46C2920E2D5347C029F60CB7 | sha1: 651657641ED5D419B382C191626B7EFDF2B7EC75 | sha256: 395DD725BDD34BC7BF9CCE7AE5A4D379A67D8EF436219BCA4C6F1355D033336A | sha512: C3E6778D4451084BAA11A87F678F1A729ADE8358876A3B27CABC20A8C7E8979C12955D588734F1845B0677FEFD8B7FAEEEE64DBAA96037D1F89384A5411C20CF
md5: 96CB06FF5A84E4E90591973BF99A7D45 | sha1: F770313A4C25328B06C3223E934B12C5CB323F68 | sha256: 3D17996B4C4F669F0FE27C9672E9FA71A39E997E09AC020C077EDEC682570CE8 | sha512: 0A86425A4C1BE59539BFD15101A0C197886C3E9EC94AA697A212405668802B7FFB23F2AB25D8E649251998698094BFFBCF392BF157FFD8485DBA00E9AE645295
md5: 123AD0908C76CCBA4789C084F7A6B8D0 | sha1: 86DE58289C8200ED8C1FC51D5F00E38E32C1AAD5 | sha256: 4E5D5D20D6D31E72AB341C81E97B89E514326C4C861B48638243BDF0918CFA43 | sha512: 80FAE0533BA9A2F5FA7806E86F0DB8B6AAB32620DDE33B70A3596938B529F3822856DE75BDDB1B06721F8556EC139D784BC0BB9C8DA0D391DF2C20A80D33CB04
md5: 0F8E4992CA92BAAF54CC0B43AACCCE21 | sha1: C7300975DF267B1D6ADCBAC0AC93FD7B1AB49BD2 | sha256: EFF52743773EB550FCC6CE3EFC37C85724502233B6B002A35496D828BD7B280A | sha512: 6E1B223462DC124279BFCA74FD2C66FE18B368FFBCA540C84E82E0F5BCBEA0E10CC243975574FA95ACE437B9D8B03A446ED5EE0C9B1B094147CEFAF704DFE978
md5: 4FF168AAA6A1D68E7957175C8513F3A2 | sha1: 782F886709FEBC8C7CEBCEC4D92C66C4D5DBCF57 | sha256: 2E4D35B681A172D3298CAF7DC670451BE7A8BA27C26446EFC67470742497A950 | sha512: C372B759B8C7817F2CBB78ECCC5A42FA80BDD8D549965BD925A97C3EEBDCE0335FBFEC3995430064DEAD0F4DB68EBB0134EB686A0BE195630C49F84B468113E3
ordlookup
pefile
peutils
psutil
md5: D30149D319EFCAECF0A5C5E71EF6CB39 | sha1: 99BEEB17BFC69E8370036F9457EDB4D6812B22E2 | sha256: 9C7FC855D9D1614E70705C7DCC6F4AC3CDCAB5ADFEB6A67D382F5ADE09EADC15 | sha512: B6FB265F0EFED56FDD3455ED620E1FB581D40D2B23B92544CCCBF331E30DC29592C4297E3FAAF437A9D1A33099E0B48D5B2344943FB7B581A448F6C5806ACEC6
md5: 0351DC34C06A7E74E977C142A8784DA8 | sha1: 1096BC9B3AE3A57DC7F684D53191DF5365889164 | sha256: B93E6083EB06137CC9191DAC0D9CF4483E47192113D3AC2228B4549F737BAC85 | sha512: 92CAEE00CC0588D30659D4B0BDE38BF229BEAB0FC07D9AAC362B84814B6EA541C39C03ABA936124CBFD5D60C219D01CB09EBA8005DD2236774503094CBDC609B
md5: 01B946A2EDC5CC166DE018DBB754B69C | sha1: DBE09B7B9AB2D1A61EF63395111D2EB9B04F0A46 | sha256: 88F55D86B50B0A7E55E71AD2D8F7552146BA26E927230DAF2E26AD3A971973C5 | sha512: 65DC3F32FAF30E62DFDECB72775DF870AF4C3A32A0BF576ED1AAAE4B16AC6897B62B19E01DC2BF46F46FBE3F475C061F79CBE987EDA583FEE1817070779860E5
md5: 0FE6D52EB94C848FE258DC0EC9FF4C11 | sha1: 95CC74C64AB80785F3893D61A73B8A958D24DA29 | sha256: 446C48C1224C289BD3080087FE15D6759416D64F4136ADDF30086ABD5415D83F | sha512: C39A134210E314627B0F2072F4FFC9B2CE060D44D3365D11D8C1FE908B3B9403EBDD6F33E67D556BD052338D0ED3D5F16B54D628E8290FD3A155F55D36019A86
md5: 9002E0BEE6455B2322E3E717FE25F9BE | sha1: BC8DF83CC657F0F46A0BFF20565870A435ED1563 | sha256: 24B47C966B6E4A65B3E4DF866D347D3427E9BD709BE550C38224427EB5E143D3 | sha512: 28DDD087B48D5AA96EC39CCC29A4020CF75AE3C5CB6AF9A9571694D73F7AAA4FECB15336C9C7A7D12C93D8BF12EFA4FE4D8D612CD93D72C72130CAE52317D0D9
md5: 83BBECF92FB68795A620B395998B131B | sha1: 026F9E87A5623FE9370C2EEDEF24C765F7312800 | sha256: B04DE4541863BC7D8879040A78889C4849C1B1DA2784C4630F734C146C2998CE | sha512: C63CA8863F63C8F415D685EFF991A1AA67E3457AC2B1F6524DB271C2986F7E79415F98F212E1F7CDD644F41BC48D558661E1136716D63F81675F664E53FDFC70
md5: 8B1CE7C4AE80F5A2EF4D968E5A78B8D6 | sha1: 1C0914DE24F41D80F572D9D8238A11E25DBC0D78 | sha256: 130C6EF3C126E97AAEC1A5CB1C638D7404473A3DDA837D6E161C69DB7A5BC339 | sha512: BF03ED7FE74DD3A721B437D123BC9185F4F19B96CC0A39440EDEAD78B73919E3E12CFEB3AC462B8C6446CAE50E1D362A30E7D83C7E08E612DA404AD50672D335
md5: C9E8AF54833D05FE951DB2DE478CAC98 | sha1: 6E76BFFC86743ED979FB0E89AAFB0E03789666DE | sha256: AE656B4D85FED20042A7FB2F4F71BD0C14B4797C740BEDC005805F1040B73B83 | sha512: 5FD9380E24BCAEEE631CD00D660E19E7241C7C88526175975D55D97CA78515D89E714E0C88D1F60F2AE5BFAEE037BD118B6E437307289E12882F77391CEAC43F
md5: 4EB97AA3C5B281F569B3D36333E41676 | sha1: BE91E80352C58FFF117CBCE22EFCB65AF43B1DF3 | sha256: 8ABD12EE2F4D06B9BC087D92BC40DD2650F46CE7B8DE587B97BBBD00F19A0F13 | sha512: DAAEDCDAC26BC9E40B320937C2686FE5A0F9303505F522162ED28EA0B957C7957E96DCBAC8F97AA68C9A7178BE2632069C92DD067F0FE626D1758CF8A09EFDAF
md5: 3822896DE6580302131F062A3E7BAB7F | sha1: 592F88AD9F910BFDB33DA6CD5302F6F8B3A4FF5B | sha256: C26405E75605B36005FA2AE96B6328D5ABCC78A393DAE7B64913F699E449F1D3 | sha512: 40BD0858A33CF755F911139AA4DC899CB1825E8E76759B80405353853931BE6CCA421737D31C2F85B32B2A663B263C34B52D3F45EE7853EF6CBC5CDC36030E34
md5: 89CD5CD993C33CE2C984FC56A6B63736 | sha1: 9B2EA7295D495E920DC93376E1F9513A33525A25 | sha256: FFFC85222EC59321D0134F82E6517B6D76DB8443A11871C74DDC9521DE5EA22A | sha512: AF7122AF0A4C2E60A852FC8EABE2F4ED80F27E4BBA8056CE8F55EED6348DE600CDEE2CC15FF481773B5D5815ECAB974CBC855CC59DFA0F984CCE1448A77B3C6F
md5: 971DBBE854FC6AB78C095607DFAD7B5C | sha1: 1731FB947CD85F9017A95FDA1DC5E3B0F6B42CA2 | sha256: 5E197A086B6A7711BAA09AFE4EA7C68F0E777B2FF33F1DF25A21F375B7D9693A | sha512: B966AAB9C0D9459FADA3E5E96998292D6874A7078924EA2C171F0A1A50B0784C24CC408D00852BEC48D6A01E67E41D017684631176D3E90151EC692161F1814D
md5: 6BC084255A5E9EB8DF2BCD75B4CD0777 | sha1: CF071AD4E512CD934028F005CABE06384A3954B6 | sha256: 1F0F5F2CE671E0F68CF96176721DF0E5E6F527C8CA9CFA98AA875B5A3816D460 | sha512: B822538494D13BDA947655AF791FED4DAA811F20C4B63A45246C8F3BEFA3EC37FF1AA79246C89174FE35D76FFB636FA228AFA4BDA0BD6D2C41D01228B151FD89
md5: 62166A6026D3165CA782F6C947C2BF33 | sha1: F63521AD9FCB7DF3B383AC52B7804B4521CF66CE | sha256: D15BAD4BC1868F563521768D58F08AF1C83619033D1B5547FBFD45C59DE890E4 | sha512: B56BFA4617A154F1D492C96EF6788C73ED5F1D09AAA5C971D2DE5856E000F52888820753502217C71974F4777891634D41BB454911F4F16EDE17C4569347AC88
md5: 95FA1B35CBD5C7D9959ADB104DA95266 | sha1: 08C94F58BF50C962EC1A559D972C30745984F976 | sha256: 30B04BBC4942671C3069DF4FCEFB3C51195B43564CCD14655E699F19FE6F1FED | sha512: 5A7E8FEC3C3E0A9FB6F01229258FC017FA125AAA71E1AF1655051F4087ACD4D90B96406C0EBC1B7F8CF96C358D6C9C6D3E8215AE34A706BDC2CC438E0B6D5F50
md5: 6DC8813089C358772EB3FB84961BF8EE | sha1: EBF724BC3048419144911EEA50FA5F6D4E7EA4FB | sha256: 20B9DF7340C666ED296099A35C951ECBB9F6FF6E4E440E5C43DA65A37E4B72D0 | sha512: DD501B8E4D667E168442EFAEFC35E6F8E8347367E8372B0D92003668F49F2AF8CA18AEB2FF95AE6917362DF66B9E302C6A0D15816D0679C22CACC9C64898EA01
md5: DC7C91AFBC6765013234561C5E4FDB3A | sha1: C3764382878B4190091FD3E7077EEFBB24B064F9 | sha256: 6AA0489C5D5673D1EECEB50C631AB35E848E828DA3B74CCC16584185ABADE613 | sha512: 04CC1F89DF0E921478D81727BCC132900B3887DD93C5079A0E86E3BD8D0B7721DE824540F822767FC23CC1B2719A1892B0BDAB8801103C40EBA0C4449D82A9EE
md5: A0D9E077D3B1C3518024F2EF9BF9C22D | sha1: 0D22AAD4A2B35D8B4690641384B6010AC10DB423 | sha256: 02F89C77E9CD1FF4938975F14F62852665089FF23764427ABBE753149A06E0EB | sha512: 49FFFF09C0C960A1BA34E69DDE0CF913CADBB03D315F0E28B7B623B9FCF6EC6CB80382E69B73F39010563065DA80742B4B2CE1C8CF97EBF09F564B0B08201598
md5: EA4BD3EC9573080ADA6A3B0C19C523D6 | sha1: F41425A4E8FC301F5A062D74E685D6B1D7840330 | sha256: 3E8FE971795FE63647EFD6C79F89486BCEACD8F5008F3382C0F5A5474EF52F4E | sha512: 7E5659D1C576AECA96B11AC4E70D3B8FE5562D799FB8A28C604FB7D75C23953A3CFCB2C3FCE2725ECCC99C56E3D5EE7B1731EA7F6AE28F4C0D06FB042807BDA1
md5: 744001DDD9405FE0A0F02D7863E789C8 | sha1: A68C7110269580305936CB516B133816F054CED3 | sha256: 77A11962166D4400914B757F9142680FB627652CB9EFFA534909CB5D157260FC | sha512: F5F5C5DCEAABE0C8110FA46CF9E6AA7FCF9E7175EB20E825315674F946A4C33497FE910C9FBF72898A73B3F1965164951F102DE5BD7B2868FC36DAB50D7C551C
md5: CFD30C65825F3F6DC7E4C9F7C48DE332 | sha1: 2DDE793D39F018A5ED069EDFF311C79B089A789F | sha256: DFD2242DD6B8371F246E1DC05C0C94A2E866E88FDB39F1BA28CA2FFBC8DCD0CA | sha512: 7378CB2428C4112AC7B58F54D4848BA81727526B369EB321EF7E6AADF09F2990930C068B4EF18C32D91C9B846F01B7C64F4446A241D986FBDAD41284FDEE00E5
md5: 40A3837648FDEADD195B59A4C3E20C94 | sha1: A0108558F0DC95EFC8C9FEA5BA070FB283769BAF | sha256: 5E8CA31932BD02274D0680EEB6C351C4F148A23A276E0CED05787C15B5E2B7E4 | sha512: 7E930F7A282AEB44213547C976069EE1B70D15D3F86222E5FF7F7EC24299A4D9B683DBAE51C6312E0EE50D419E7FF380B09AE6EB21F89B5EFAA608C3160C48CF
md5: CF4290160044637E13FD91854613D6A3 | sha1: D179D598B3D3CDFA7BA4FA1330B7F34B87D9D375 | sha256: 9EE334A38EB524ABCF1CB3166A6056153D2522ED0902713FCCE4F5AD63307CA5 | sha512: 22B83ABD036F83920AFEC470F9394A3777CBF8DB37A4C26E9DA2DCA0AA15F58A5166A25897DCC9343AA64F3A504BC7A98BA4A1D91F11A6663DBC6A6C9C6DBF35
md5: 3085EF7BAFE9C2FBAF9BF11A87E6CD47 | sha1: 0C46C0BC9AF60A6311A4F812DB28EE0806A7BAD6 | sha256: 3DD16C2607326C08FA4E2617CE819F7358E1FABD120BACB16246453688A54927 | sha512: 74654F3411672A4E46D2413270E77BA2AB5C4D18E2C4AA75AE8CBF072F2D38B5E43F65A3A6E353EC00BECA4777F912DDF919D278713067CD3F5BCA56A9650B00
md5: 573C0E3279EC3991BC875167237642BC | sha1: 591C632AC9CF973B472BBB696C1731AFEDEB9C7E | sha256: 271B1E73D097818C0847303DE77209D111D5BFF850B057D211F9879A8DA52F80 | sha512: CA005EE8D2BB83827232988633578FE7393F349ACFDFC12C4A3F8925C0C71337BCF9033BA4C8986B4628DFD0994BA312EFB5DAD6302552F4FC99C4112F64C93C
md5: ED7ED02F3EB2E04AB83A61622AA07F51 | sha1: 634B0EDA080161D2AD7A63668C1F4625307BA66B | sha256: D77AEF3DB370627248059CFA25B40CAAD027D3DA520B4A8FD96A0DB7D0CE60C5 | sha512: 86864610D280BC1DE3E4B4FBB18A13771788DC62D3EBBC721EE08A7F110B5830884BB3F5D8330CABBD0CD1AF978F6DD0618B32C50208B9E2F5744AB11092B3C9
md5: 2C9BB2E8E16AE3AE625A47306703D12C | sha1: 3CABC6B832F03EA845604EF7965C8FFEA0FC5CBA | sha256: 67B2C0670003A135D2F829A709F934B788113EC59CFD57456F098086F3CC87F1 | sha512: 45FA77534EC51BACDF5864316EAB6E0CF4F97549985E74D099DCB4590235E9A7FAD02D29A43E412A305863AF93A947E8BF72D460A8892867197BA178FD35515D
md5: CBB594A2C2708F51F83134D527A01CD5 | sha1: 49FE8B62A9F22FCA19DEC80A77C1E6AA1698E0FC | sha256: 338B06B75F2AB5A95738AD464D4E3252C72A3B2DE1C554E0EC223D83209E124E | sha512: 93049CD5B0E36F1155CDAD1FD4ED8C4191745CD88FC9C0C4A4F1DBB8FF67938F2406E62ADB2CF6030B439971084AFA8C59657EE3BFC8DD8A09CDEEC2CA7047D4
md5: C530EC3F535E240809312C791B414499 | sha1: E465B44326A9EEEDC64E520D83B489C995E06E96 | sha256: 12AAA9181D58750BD2AEB2E0EE239E730A14F1F51822BAB15C9245480256D26E | sha512: 30056E718C27A44312CB9D03139E7095099BEB6A84C748DE4C7D668220AFCBC50498A5D19D31F1DF5F3E2F753865C7E622A246DF4C12B20BE719570E9D392369
md5: 8FACC432FC339E343A665F2EEFE2C09B | sha1: 121CE3C65C94BD7C11B25D3B8D3B9C7B08DA9BFE | sha256: 170EC984BCCF11DED5272174E31E3AB74FBFDB78EF1E0D5312BF9E40476C65A6 | sha512: 539B7FA94CCA9E252904109ADC008181746E18C85C9FA66185D1BC97D4D2060D316DB9C89E1386CF3EE43A439AC019E2FCFBF6A339EA4FC20090060D68C9595B
md5: 4CF045FE131895540719F8EED8A6702B | sha1: 75549943572DE0F891857030DC8A7F19461C1133 | sha256: 20D6242DD3D4CC47D8E531FAA364F0F695D750DC6CC6B0BD0CA9E18C176F3DFF | sha512: D0D9C7988A9702449ACC72092239E5207CC0F69F9CCDB4C42A0225D6C7DAFBD3A5ED6C0D8BEAE744BB176252960E573DF4DCA53A2852334C1F95E4C90E920501
md5: 19216D581E072FCD6E38B8D0F54F2564 | sha1: B39AC076F5F117192ACBC9848B18C22D353746FB | sha256: 9D217CBB2F2C059850852D466C77D3C641078F9CFBE2C544588B23C2E3561F26 | sha512: 410BB4762E82919AE25716E0773CC15A5873FCD53091484A2FFC4CDE0F1AE7DE51942647F9E579D6651400B693A4C97D6DB2A2FDB4C6BD31DF5043D2C1217273
md5: 98B008BE9834BFC362B4C2EEF4E8CDB9 | sha1: A4A50CED1329C3986E3C1576F089B25AFF5FFDF2 | sha256: 4F93342B59ADDEDBE45EBD973E6449AB85B11C0AAB6AD7962124E293C5D03638 | sha512: D594FFD7D44D4D862475711973DF87B08FB63A900DDFD87C7771AD27F0CC71E5FBDCE92DA4D4AD5856FE3CFB803257CE0B71CD8DC24CA5C421DDB1B9B44C7881
md5: 501080884BED38CB8801A307C9D7B7B4 | sha1: 881B250CC8F4FA4F75111AC557A4FDE8E1E217AF | sha256: BF68CF819A1E865170430C10E91C18B427AEF88DB1DA1742020443864AA2B749 | sha512: 63D74A4871D1C72C2A79AE8A5D380070F9D2128C16949C3AD36C9862FCC4DAB738137ED3D51CAF0BC46B36655F8BD8A2D425D68200123415EE8D4DE0E1CBEBC9
md5: 7B4BD20267C93E35C49C32AAD05B6B15 | sha1: 860A10D04C8764F540ED34CF08E06F32B7B37611 | sha256: 90BA935A0145EE9AE56267A365CC0088D34FA506B7AFEB2BD1BD78CD33359605 | sha512: 9E05566461D9BE1A234057E1AE9979B6D022189CB49B2C264C9AD253ABEC0F0235919F24159638ACCC45FA3E75AB324DB8EDF737E72DB1EFDA2CFA589531DDFB
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.
Version 2.6.8:
Updates to the RR DLL to version 310.2.1.0.
Updates the frame generation DLL to version 310.2.1.0.
md5: 2663E22900AB5791C6687A264473AE1E | sha1: D8DB587B6C632200AE13BE880CC824CDC8390DF9 | sha256: BAEE284995B22D495FD12FA8378077E470978DB1522C61BFB9AF37FB827F33D1 | sha512: 5F29FF4288B9DB33976F5F79B9FD07C4900A560BB41FE98C93A33DA7A36C0981FFD71F460E81E13E4F6A2DEBAFA6D9284BC1A728734752BA5AD5FBD766659E80
importlib_metadata
[console_scripts]
wheel=wheel.cli:main
[distutils.commands]
bdist_wheel=wheel.bdist_wheel:bdist_wheel
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.
md5: 286B308DF8012A5DFC4276FB16DD9CCC | sha1: 8AE9DF813B281C2BD7A81DE1E4E9CEF8934A9120 | sha256: 2E5FB14B7BF8540278F3614A12F0226E56A7CC9E64B81CBD976C6FCF2F71CBFB | sha512: 24166CC1477CDE129A9AB5B71075A6D935EB6EEBCAE9B39C0A106C5394DED31AF3D93F6DEA147120243F7790D0A0C625A690FD76177DDDAB2D2685105C3EB7B2
md5: C0B4C55CE3711AF914B2015F707E4452 | sha1: F1C1E9F8A461CFEE1199D2100F5C0796733518B6 | sha256: A67EEC238162FDE20AC24CA7DF931792734AAD0611BE22D1B3A71BC15ACF72F3 | sha512: FA6BD9223898EF0C54CA9A67B10207BFCE152EADBAEC4C91D4E951D0790F455066F5095ED739FA2452AEA1420D154BEB00BFA9E6E10B46BED687C5D0D7484900
md5: 862F820C3251E4CA6FC0AC00E4092239 | sha1: EF96D84B253041B090C243594F90938E9A487A9A | sha256: 36585912E5EAF83BA9FEA0631534F690CCDC2D7BA91537166FE53E56C221E153 | sha512: 2F8A0F11BCCC3A8CB99637DEEDA0158240DF0885A230F38BB7F21257C659F05646C6B61E993F87E0877F6BA06B347DDD1FC45D5C44BC4E309EF75ED882B82E4E
md5: 68156F41AE9A04D89BB6625A5CD222D4 | sha1: 3BE29D5C53808186EBA3A024BE377EE6F267C983 | sha256: 82A2F9AE1E6146AE3CB0F4BC5A62B7227E0384209D9B1AEF86BBCC105912F7CD | sha512: F7BF8AD7CD8B450050310952C56F6A20B378A972C822CCC253EF3D7381B56FFB3CA6CE3323BEA9872674ED1C02017F78AB31E9EB9927FC6B3CBA957C247E5D57
md5: 747FC8B90E33F5E9048BCF26788B9169 | sha1: AC30AAE15BEA0514C7730B007B68DD841A7F3DDC | sha256: B1B1BB33AF9CC14749936B1F6BAC36B2FFC494EC1A5FB8B12FC9180A6454F545 | sha512: 51416CDA9A18F113D46C3CB06E7ED85717C64325156BE16C4FC78BDDC7A06F0E845B3FEDD2C1CA6C965517530D9CBB9B9497DD1B309BC16011D2E1499BB5D082
md5: 70DEC3CE00E5CAF45246736B53EA3AD0 | sha1: 3CD7037D211EBF9BD023C248EC6420F193AD7ED2 | sha256: 8CEF0CD8333F88A9F9E52FA0D151B5F661D452EFBCFC507DC28A46259B82596C | sha512: EDDBEB527C01167FB69D9C743495C868073B5CACAE3652D777B6A635C4FEB0344F085BDC2AEB6A775FFEF8056394DDB4DF5CD47E622CCBF974D11C30857FD536
md5: 057325E89B4DB46E6B18A52D1A691CAA | sha1: 8EAB0897D679E223AA0D753F6D3D2119F4D72230 | sha256: 5BA872CAA7FCEE0F4FB81C6E0201CEED9BD92A3624F16828DD316144D292A869 | sha512: 6BC7606869CA871B7EE5F2D43EC52ED295FA5C3A7DF31DBD7E955DDB98C0748AFF58D67F09D82EDCDE9D727E662D1550C6A9CF82F9CB7BE021159D4B410E7CBC
md5: 2185849BC0423F6641EE30804F475478 | sha1: D37CA3E68F4B2111FC0C0CEAD9695D598795C780 | sha256: 199CD8D7DB743C316771EF7BBF414BA9A9CDAE1F974E90DA6103563B2023538D | sha512: BA89DB9F265A546B331482D779AB30131814E42AD3711A837A3450F375D2910BD41B3B3258DB90B29CD5AFCCDC695318FC8AD8CD921A57CE25F69AEA539B26EE
md5: F465C15E7BACEAC920DC58A5FB922C1C | sha1: 3A5A0156F5288F14938494609D377EDE0B67D993 | sha256: F4A486A0CA6A53659159A404614C7E7EDCCB6BFBCDEB844F6CEE544436A826CB | sha512: 22902C1BCCA7F80ED064E1E822C253BC8242B4E15E34A878A623E0A562A11203B45D5FF43904268322A7EF5CEBB8E80E5FE1F1F1BCAA972E219348F84A1DAF5F
md5: EED5E3C565099640C146D512E3CEDD84 | sha1: E427D8AF6A5DC3691B61E815F034F40FD62A6053 | sha256: F7D884C475E5C98006BF7C2ABB6B5ACBD885157FB809ED2EE06D2347AB409BC0 | sha512: B93CC53A09E0B959C62BA35A804C6FCA0AFF821B77D6D72047721FA71E27D644EB98F0102DF4D33A96BF4BED447E3947EBCEDD0C798D50C46E3475D97F57127A
md5: CF4120BAD9A7F77993DD7A95568D83D7 | sha1: AC477C046D14C5306AA09BB65015330701EF0F89 | sha256: 14765E83996FE6D50AEDC11BB41D7C427A3E846A6A6293A4A46F7EA7E3F14148 | sha512: F905F9D203F86A7B1FC81BE3ABA51A82174411878C53FD7A62D17F8E26F5010D195F9371FA7400E2E2DC35FDA0DB0CBE68367FCAF834DD157542E9EE7A9742B6
md5: 3E73BC69EFB418E76D38BE5857A77027 | sha1: 7BEE01096669CAA7BEC81CDC77D6BB2F2346608C | sha256: 6F48E7EBA363CB67F3465A6C91B5872454B44FC30B82710DFA4A4489270CE95C | sha512: B6850E764C8849058488F7051DCABFF096709B002D2F427A49E83455838D62A9D3FC7B65285702DE2B995858ED433E35A0C4DA93C2D5AE34684BF624EB59FA6A
md5: 24AEE7D83525CB43AD02FD3116B28274 | sha1: 68A2870BD5496C959EE7E499F4472D0614FDFD87 | sha256: 3262EC7496D397C0B6BFB2F745516E9E225BD9246F78518852C61D559AA89485 | sha512: 6EF5082E83F9400E8FFDBB2F945B080085FD48C0E89E2283BCEDD193A4E6A9F533F8DA78C643DAD95DB138EC265099110A3A6DC8BC68563DBEF5CA08D5E0D029
md5: 51E4C701E4EFA92A56ADAF5BDC9CF49B | sha1: 1ADBC8B57E5EC0A90B9EC629323833DAEAD8C3B4 | sha256: 9EF177DB14CFA3AA66193078C431A96B6AE70858E9DD774B3D3E3CB6E39D10A3 | sha512: 35B2D4114AA12843CB767B7D7A2C82B00144FE8FEA04B41601B790D8B4026E271148B5186308F461F2ED70D75DF7C0AC56C4E023ED069F4F0F6F23F5EA11A2D1
md5: 59C05030E47BDE800AD937CCB98802D8 | sha1: F7B830029A9371B4E500C1548597BEB8FBC1864F | sha256: E4956834DF819C1758D17C1C42A152306F7C0EA7B457CA24CE2F6466A6CB1CAA | sha512: 4F5E7EF0948155DB6712E1BD7F4F31CB81602B325BA4E6E199F67693913B4BB70BB2C983393646C0AC0D86EF81071907D04BCEB8AB0D506B7C5AC7C389FE692D
md5: 69C4A9A654CF6D1684B73A431949B333 | sha1: 3C8886DAC45BB21A6B11D25893C83A273FF19E0B | sha256: 8DAEFAFF53E6956F5AEA5279A7C71F17D8C63E2B0D54031C3B9E82FCB0FB84DB | sha512: CADCEC9A6688B54B36DBD125210D1A742047167DAD308907A3C4E976B68483A8C6144E02D5CF26F887744DC41AF63B7731551287BB3EF8BD947C38C277783C16
md5: CE19076F6B62292ED66FD06E5BA67BBA | sha1: 231F6236BDBBE95C662E860D46E56E42C4E3FE28 | sha256: 21CA71B2C1766FC68734CB3D1E7C2C0439B86BCFB95E00B367C5FD48C59E617C | sha512: 7357598BC63195C2FD2DDDE0376B3ECF5BD0211A286F4A5C1E72E8C68B6E881E7E617F561E7A859C800FE67BEC8F4C376E7A6943CAB8DACFEDA0056B8E864143
md5: CCF609AE4416F13FCB80A122C4345348 | sha1: BE60263E7CBB2702733A37513D5FB717F6B30216 | sha256: 99E97E0AF615F43150778AAA44D82BC58B70BF595A8412CFAFCC5D38BE38BDFB | sha512: 9DFE0E4AA31E50E5B799CDC86A276C6576FFC44C919657E4230E17C9B739B8E69E0865EED38AB9EC0B07E77090A6F2C03C415E68FA431FDE108D2D92CB3E8987
md5: E3213CF44340D7B4CB65F7231A65E3A4 | sha1: 815E5809A01905ECAA463F6827F657C11B95D243 | sha256: AB87FE4B0CF5B2B17901905EA86367B9756C44845EB463E77435648F0F719354 | sha512: D32B6CB1C5A286B2CE9837051D099FEA98F9E5AD00C15B14CCCE02B4556D74C4B703B1C94A59670599BF6A9BFBF84C7C22DAC25653AF9B455999A5E42CF38B7A
Log in or click on link to see number of positives.
- VCRUNTIME140.dll (5e197a086b6a) - ## / 72
- MSVCP140.dll (88f55d86b50b) - ## / 72
- MSVCP140_1.dll (446c48c1224c) - ## / 72
- VCRUNTIME140_1.dll (1f0f5f2ce671) - ## / 71
- MSVCP140_2.dll (24b47c966b6e) - ## / 72
- libffi-8.dll (eff52743773e) - ## / 72
- opengl32sw.dll (b04de4541863) - ## / 72
- libcrypto-3.dll (4e5d5d20d6d3) - ## / 71
- libssl-3.dll (2e4d35b681a1) - ## / 71
- VCRUNTIME140.dll (36585912e5ea) - ## / 71
- VCRUNTIME140_1.dll (82a2f9ae1e61) - ## / 72
- api-ms-win-core-console-l1-1-0.dll (88ace577a9c5) - ## / 72
- api-ms-win-core-datetime-l1-1-0.dll (1bd81dfd1920) - ## / 72
- api-ms-win-core-debug-l1-1-0.dll (591358eb4d15) - ## / 70
- api-ms-win-core-errorhandling-l1-1-0.dll (d56ce7b1cd76) - ## / 71
- api-ms-win-core-fibers-l1-1-0.dll (91d249d7bc0e) - ## / 72
- api-ms-win-core-fibers-l1-1-1.dll (fc9d86cec621) - ## / 72
- api-ms-win-core-file-l1-1-0.dll (1ca895aba4e7) - ## / 72
- api-ms-win-core-file-l1-2-0.dll (4cadbc0c39da) - ## / 72
- api-ms-win-core-file-l2-1-0.dll (93c624b366ba) - ## / 72
- api-ms-win-core-handle-l1-1-0.dll (39095f59c41d) - ## / 72
- api-ms-win-core-heap-l1-1-0.dll (8f105771b236) - ## / 72
- api-ms-win-core-interlocked-l1-1-0.dll (53b25e753ca7) - ## / 67
- api-ms-win-core-kernel32-legacy-l1-1-1.dll (a9b13a1cd1b8) - ## / 70
- api-ms-win-core-libraryloader-l1-1-0.dll (7f39ba298b41) - ## / 72
- api-ms-win-core-localization-l1-2-0.dll (6ee44dd0d851) - ## / 71
- api-ms-win-core-memory-l1-1-0.dll (0512a35316ec) - ## / 67
- api-ms-win-core-namedpipe-l1-1-0.dll (c05f1fffe3b5) - ## / 72
- api-ms-win-core-processenvironment-l1-1-0.dll (c4eca98c3c67) - ## / 68
- api-ms-win-core-processthreads-l1-1-0.dll (5ccb89e93d67) - ## / 71
- api-ms-win-core-processthreads-l1-1-1.dll (4ad565a8ba3e) - ## / 71
- api-ms-win-core-profile-l1-1-0.dll (7809160932f4) - ## / 70
- api-ms-win-core-rtlsupport-l1-1-0.dll (9dc1e91e71c7) - ## / 70
- api-ms-win-core-string-l1-1-0.dll (60fc31d2a0c6) - ## / 73
- api-ms-win-core-synch-l1-1-0.dll (3a72b4f29f39) - ## / 72
- api-ms-win-core-synch-l1-2-0.dll (efc1e4460984) - ## / 67
- api-ms-win-core-sysinfo-l1-1-0.dll (b203d862ddef) - ## / 72
- api-ms-win-core-sysinfo-l1-2-0.dll (2703635d8353) - ## / 71
- api-ms-win-core-timezone-l1-1-0.dll (33f4fddc1810) - ## / 72
- api-ms-win-core-util-l1-1-0.dll (6eda016742a6) - ## / 72
- api-ms-win-crt-conio-l1-1-0.dll (b762061b688a) - ## / 72
- api-ms-win-crt-convert-l1-1-0.dll (ebb2ae5535a6) - ## / 71
- api-ms-win-crt-environment-l1-1-0.dll (17d63275d00b) - ## / 71
- api-ms-win-crt-filesystem-l1-1-0.dll (9a9e2a65a281) - ## / 72
- api-ms-win-crt-heap-l1-1-0.dll (bab9ac3ec83e) - ## / 72
- api-ms-win-crt-locale-l1-1-0.dll (bd14c67ea28e) - ## / 72
- api-ms-win-crt-math-l1-1-0.dll (606d66d82db5) - ## / 72
- api-ms-win-crt-process-l1-1-0.dll (f6156b102038) - ## / 71
- api-ms-win-crt-runtime-l1-1-0.dll (c5902934d026) - ## / 73
- api-ms-win-crt-stdio-l1-1-0.dll (a9c5a153d8c0) - ## / 72
- api-ms-win-crt-string-l1-1-0.dll (25b8f83a7767) - ## / 72
- api-ms-win-crt-time-l1-1-0.dll (7c7f6393f06d) - ## / 71
- api-ms-win-crt-utility-l1-1-0.dll (d8ba5f17b9ff) - ## / 70
- ucrtbase.dll (2e5fb14b7bf8) - ## / 72
- nvngx_dlss.dll (4e85cdbe0896) - ## / 72
- Qt6Core.dll (130c6ef3c126) - ## / 72
- Qt6Gui.dll (ae656b4d85fe) - ## / 73
- Qt6Network.dll (8abd12ee2f4d) - ## / 73
- Qt6Svg.dll (fffc85222ec5) - ## / 73
- Qt6Widgets.dll (0d07a57f8fb2) - ## / 73
- qtuiotouchplugin.dll (d15bad4bc186) - ## / 73
- qsvgicon.dll (30b04bbc4942) - ## / 73
- qgif.dll (20b9df7340c6) - ## / 72
- qico.dll (02f89c77e9cd) - ## / 73
- qjpeg.dll (3e8fe971795f) - ## / 73
- qsvg.dll (dfd2242dd6b8) - ## / 73
- qwindows.dll (338b06b75f2a) - ## / 73
- qmodernwindowsstyle.dll (12aaa9181d58) - ## / 73
- python3.dll (4f93342b59ad) - ## / 72
- python313.dll (bf68cf819a1e) - ## / 72
- pywintypes313.dll (90ba935a0145) - ## / 70
- Qt6Pdf.dll (c26405e75605) - ## / 72
- qicns.dll (6aa0489c5d56) - ## / 73
- qpdf.dll (77a11962166d) - ## / 73
- qtga.dll (5e8ca31932bd) - ## / 66
- qtiff.dll (9ee334a38eb5) - ## / 72
- qwbmp.dll (3dd16c260732) - ## / 73
- qwebp.dll (271b1e73d097) - ## / 73
- qminimal.dll (d77aef3db370) - ## / 73
- qoffscreen.dll (67b2c0670003) - ## / 73
- dlss-updater.2.7.0.nupkg (146b700acc87) - ## / 61
- DLSS_Updater.exe (9ab6bd24b887) - ## / 72
- base_library.zip (5e7c1d8f9675) - ## / 60
- nvngx_dlssd.dll (395dd725bdd3) - ## / 70
- nvngx_dlssg.dll (3d17996b4c4f) - ## / 72
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.7.3 | 22 | Thursday, May 8, 2025 | Approved | |
DLSS Updater 2.7.2 | 66 | Wednesday, April 23, 2025 | Approved | |
DLSS Updater 2.7.1 | 57 | Tuesday, April 8, 2025 | Approved | |
DLSS Updater 2.7.0 | 37 | Saturday, April 5, 2025 | Approved | |
DLSS Updater 2.6.8 | 53 | Thursday, March 27, 2025 | Approved | |
DLSS Updater 2.6.7 | 107 | Saturday, February 1, 2025 | Approved | |
DLSS Updater 2.6.6 | 13 | Thursday, January 30, 2025 | Approved | |
DLSS Updater 2.6.5 | 19 | Saturday, January 25, 2025 | Approved | |
DLSS Updater 2.6.4 | 151 | Monday, January 13, 2025 | Approved | |
DLSS Updater 2.6.3 | 19 | Thursday, January 9, 2025 | Approved | |
DLSS Updater 2.6.2 | 50 | Friday, January 3, 2025 | Approved | |
DLSS Updater 2.6.1 | 34 | Saturday, December 28, 2024 | Approved | |
DLSS Updater 2.5.2 | 57 | Thursday, December 19, 2024 | Approved | |
DLSS Updater 2.5.1 | 49 | Saturday, December 14, 2024 | Approved | |
DLSS Updater 2.2.6 | 49 | Thursday, November 14, 2024 | Approved | |
DLSS Updater 2.2.3 | 171 | Thursday, September 26, 2024 | Approved |
-
- chocolatey-core.extension (≥ 1.1.0)
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.