Skip to content

Commit a6841ed

Browse files
authored
Merge pull request #5 from TantalusDrive/main
Improve AMD OpenCL ICD script: batch enhancements & new PowerShell implementation
2 parents 6fbdf5b + be1e0fe commit a6841ed

3 files changed

Lines changed: 282 additions & 67 deletions

File tree

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,36 @@ It will scan your system for *OpenCL Installable Client Driver (ICD)* files by A
99
- amdocl12cl64.dll
1010
- amdocl32.dll
1111
- amdocl64.dll
12+
- versioned variants (e.g. amdocl_\*.dll, amdocl64_\*.dll)
13+
14+
The scripts ensure proper detection and registration of the drivers, including handling SysWOW64, scanning the PATH safely, registering versioned DLLs and avoiding duplicate entries.
15+
The PowerShell version additionally verifies DLL signatures, detects 32/64-bit bitness more reliably, safely cleans up or moves invalid entries, handles DriverStore and versioned DLLs intelligently and provides more detailed error reporting and status output.
1216

1317
## Usage
18+
## Batch script
1419
1. Make sure to have the latest [AMD drivers](https://www.amd.com/en/support) installed
1520
2. Download and execute `amdocl.bat`
1621
3. Run the file as **Administrator** (Right click file and select `Run as Administrator`)
1722

23+
## PowerShell script
24+
1. Download `amdocl-fix.ps1` and place it in a folder of your choice.
25+
2. Make sure to run it as **Administrator**:
26+
- Right‑click the file → **Run with PowerShell** → confirm the UAC prompt.
27+
- Alternatively, open PowerShell as Administrator and run:
28+
```powershell
29+
cd "C:\path\to\folder"
30+
.\amdocl-fix.ps1
31+
```
32+
33+
## Compatibility
34+
- Windows 10, 11: fully supported
35+
- Windows 7, 8, 8.1: batch script fully supported; PowerShell script (`amdocl-fix.ps1`) requires PowerShell 5.1 or newer
36+
- Windows XP / Vista: script runs safely, but OpenCL drivers may not be present
37+
1838
## Notes
1939
Inspired by StackOverflow https://stackoverflow.com/a/28407851
2040
2141
---
2242
23-
© 2023 [Patrick Trumpis](https://github.com/ptrumpis)
43+
© 2023 [Patrick Trumpis](https://github.com/ptrumpis)
44+
© 2025 [TantalusDrive](https://github.com/TantalusDrive) (Additional improvements and PowerShell version)

amdocl-fix.ps1

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# PowerShell script to manage and fix AMD OpenCL ICDs
2+
#
3+
# Original batch concept: Patrick Trumpis (https://github.com/ptrumpis/OpenCL-AMD-GPU)
4+
# PowerShell implementation and extensions: TantalusDrive (https://github.com/TantalusDrive)
5+
#
6+
# Licensed under the MIT License.
7+
# See LICENSE file in the repository root for full terms.
8+
#
9+
# This PowerShell script extends the original batch by safely cleaning up
10+
# invalid or misplaced registry entries and coherently registering AMD
11+
# OpenCL DLLs in the correct 32-bit or 64-bit hive, and providing detailed status output.
12+
# By default, unsigned DLLs are allowed to prevent accidental removal.
13+
#
14+
# Tested on a couple of dated AMD GPUs (R5 M330, R5 M430), feedback and contributions are welcome.
15+
16+
param(
17+
[switch]$AllowUnsigned = $true
18+
)
19+
20+
$roots = @(
21+
"HKLM:\SOFTWARE\Khronos\OpenCL\Vendors",
22+
"HKLM:\SOFTWARE\WOW6432Node\Khronos\OpenCL\Vendors"
23+
)
24+
25+
$scanDirs = @(
26+
"$env:WINDIR\System32",
27+
"$env:WINDIR\SysWOW64",
28+
"$env:WINDIR\System32\DriverStore\FileRepository"
29+
)
30+
31+
$hadErrors = $false
32+
33+
function Get-DllBitness {
34+
param([string]$Path)
35+
try {
36+
$fs = [System.IO.File]::Open($Path, 'Open', 'Read', 'Read')
37+
$br = New-Object System.IO.BinaryReader($fs)
38+
$fs.Seek(0x3C, 'Begin') | Out-Null
39+
$peOffset = $br.ReadInt32()
40+
$fs.Seek($peOffset + 4, 'Begin') | Out-Null
41+
$machine = $br.ReadUInt16()
42+
$br.Close(); $fs.Close()
43+
switch ($machine) {
44+
0x8664 { return 64 }
45+
0x014C { return 32 }
46+
default { return $null }
47+
}
48+
} catch { return $null }
49+
}
50+
51+
function Safe-Remove {
52+
param($root,$name)
53+
try { Remove-ItemProperty -Path $root -Name $name -Force }
54+
catch { $global:hadErrors = $true }
55+
}
56+
57+
function Safe-Add {
58+
param($root,$name)
59+
try { New-ItemProperty -Path $root -Name $name -Value 0 -PropertyType DWord -Force | Out-Null }
60+
catch { $global:hadErrors = $true }
61+
}
62+
63+
function Is-SignatureAcceptable {
64+
param($sig, $AllowUnsigned)
65+
if ($sig.Status -eq 'Valid') { return $true }
66+
if ($AllowUnsigned -and ($sig.Status -eq 'NotSigned' -or $sig.Status -eq 'Unknown')) {
67+
return $true
68+
}
69+
return $false
70+
}
71+
72+
function Register-OpenCLDLL {
73+
param([string]$dllPath, [switch]$AllowUnsigned)
74+
if (-not (Test-Path $dllPath)) { return }
75+
$sig = Get-AuthenticodeSignature -FilePath $dllPath
76+
if (-not (Is-SignatureAcceptable $sig $AllowUnsigned)) { return }
77+
$bit = Get-DllBitness $dllPath
78+
if ($bit -eq 64) { $root = $roots[0] }
79+
elseif ($bit -eq 32) { $root = $roots[1] }
80+
else { return }
81+
$exists = (Get-ItemProperty -Path $root -ErrorAction SilentlyContinue).PSObject.Properties |
82+
Where-Object { $_.Name -eq $dllPath }
83+
if (-not $exists) {
84+
Safe-Add $root $dllPath
85+
Write-Host "[+ $bit bit] Added: $dllPath" -ForegroundColor Cyan
86+
}
87+
}
88+
89+
# Registry cleanup: remove invalid, missing, or misplaced entries
90+
foreach ($root in $roots) {
91+
Write-Host "`nAnalyzing: $root" -ForegroundColor Cyan
92+
$entries = Get-ItemProperty -Path $root -ErrorAction SilentlyContinue
93+
if (-not $entries) {
94+
Write-Host "No entries found or key missing."
95+
continue
96+
}
97+
foreach ($prop in $entries.PSObject.Properties) {
98+
$dll = $prop.Name
99+
if ($dll -notlike "*amdocl*.dll") { continue }
100+
if (-not (Test-Path $dll)) {
101+
Write-Host "Removed: $dll (file not found)" -ForegroundColor Yellow
102+
Safe-Remove $root $dll
103+
continue
104+
}
105+
$sig = Get-AuthenticodeSignature -FilePath $dll
106+
if (-not (Is-SignatureAcceptable $sig $AllowUnsigned)) {
107+
Write-Host "Removed: $dll (invalid signature)" -ForegroundColor Yellow
108+
Safe-Remove $root $dll
109+
continue
110+
}
111+
$bit = Get-DllBitness $dll
112+
if ($bit -eq $null) {
113+
Write-Host "Removed: $dll (architecture not detected)" -ForegroundColor Yellow
114+
Safe-Remove $root $dll
115+
continue
116+
}
117+
$correctRoot = if ($bit -eq 64) { $roots[0] } else { $roots[1] }
118+
if ($correctRoot -ne $root) {
119+
Write-Host "Moved ($bit bit): $dll" -ForegroundColor Yellow
120+
Safe-Remove $root $dll
121+
$existsDest = (Get-ItemProperty -Path $correctRoot -ErrorAction SilentlyContinue).PSObject.Properties |
122+
Where-Object { $_.Name -eq $dll }
123+
if (-not $existsDest) {
124+
Safe-Add $correctRoot $dll
125+
}
126+
continue
127+
}
128+
Write-Host "OK: $dll" -ForegroundColor Green
129+
}
130+
}
131+
132+
# Register all valid DLLs found in each directory (no duplicates)
133+
Write-Host "`nRegistering all valid AMD OpenCL DLLs from standard directories..." -ForegroundColor Cyan
134+
135+
foreach ($dir in $scanDirs) {
136+
if (-not (Test-Path $dir)) { continue }
137+
Get-ChildItem -Path $dir -Filter "amdocl*.dll" -Recurse -ErrorAction SilentlyContinue |
138+
Where-Object { $_.VersionInfo.FileVersionRaw } |
139+
ForEach-Object {
140+
Register-OpenCLDLL -dllPath $_.FullName -AllowUnsigned:$AllowUnsigned
141+
}
142+
}
143+
144+
if ($hadErrors) {
145+
Write-Host "`nCompleted with warnings." -ForegroundColor Yellow
146+
} else {
147+
Write-Host "`nCompleted." -ForegroundColor Green
148+
}
149+
150+
# Optional PATH scan
151+
Write-Host "`nDo you want to include an extended scan of system PATH directories? (Recommended only for custom or unofficial DLLs)" -ForegroundColor Yellow
152+
$input = Read-Host "Type Y to scan, anything else to skip"
153+
if ($input -eq 'Y' -or $input -eq 'y') {
154+
Write-Host "`nNote: DLLs found in PATH may be unofficial or obsolete." -ForegroundColor Magenta
155+
$pathDirs = ($env:PATH -split ';' | Where-Object { Test-Path $_ })
156+
foreach ($dir in $pathDirs) {
157+
Get-ChildItem -Path $dir -Filter "amdocl*.dll" -Recurse -ErrorAction SilentlyContinue |
158+
Where-Object { $_.VersionInfo.FileVersionRaw } |
159+
ForEach-Object {
160+
Register-OpenCLDLL -dllPath $_.FullName -AllowUnsigned:$AllowUnsigned
161+
}
162+
}
163+
Write-Host "`nPATH scan completed." -ForegroundColor Cyan
164+
} else {
165+
Write-Host "`nPATH scan skipped."
166+
}
167+
168+
Read-Host "Press Enter to exit"

0 commit comments

Comments
 (0)