Keyence VR-6000 Series Software + USB driver deployment
- shopfloor-setup/Keyence/09-Setup-Keyence.ps1: populate placeholder with
MSI install via msiexec and driver install via pnputil. Idempotent on
ProductCode {058E7194-...} and DriverStore entry. Logs to C:\Logs\Keyence\.
- shopfloor-setup/Keyence/installers/VR-6000 Series Software.msi: main
product (1.7 MB; pulled from Keyence6000.exe Inno wrapper's Windows
Installer cache, built with InstallShield 2019).
- shopfloor-setup/Keyence/drivers/: KEYENCE VR Series USB driver
package (.inf + .cat + Wdf/WinUsb co-installers). 2.7 MB, pulled from
DriverStore\FileRepository\keyence_vr_series.inf_amd64_b5e5eb0924d7b4ce.
- preinstall.json: add VC++ 2013 x64 Min + Add entries (PCTypes: ["*"])
as prereqs for VR-6000. GUIDs {A749D8E6-B613-...} and {929FBD26-9020-...}.
Staging footprint for non-Keyence PCs is unchanged (the 4.4 MB Keyence
payload lives under shopfloor-setup/Keyence/ which startnet.cmd only
xcopies for PCTYPE=Keyence). Rollout still requires dropping the two
VC++ 2013 x64 MSIs into \$PXE_IMAGES_DIR/dependencies/vcredist/2013-x64-{min,add}/
on the workstation running sync-preinstall.sh.
Rationale for bundling the MSI + driver locally rather than running
Keyence6000.exe: the Inno wrapper calls an InstallShield child (Setup.exe)
without silent flags, which hangs indefinitely in session 0 during
automated imaging. msiexec + pnputil from the extracted bundle runs
fully non-interactive.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -71,6 +71,26 @@
|
|||||||
"DetectionPath": "HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F8CFEB22-A2E7-3971-9EDA-4B11EDEFC185}",
|
"DetectionPath": "HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F8CFEB22-A2E7-3971-9EDA-4B11EDEFC185}",
|
||||||
"PCTypes": ["*"]
|
"PCTypes": ["*"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"_comment": "VC++ 2013 x64 Minimum Runtime - required by Keyence VR-6000 Series Software. Extracted from the Keyence installer's Windows Installer cache. Same REBOOT=ReallySuppress pattern as the x86 variants.",
|
||||||
|
"Name": "VC++ Redistributable 2013 x64 (Minimum)",
|
||||||
|
"Installer": "vcredist/2013-x64-min/installer.msi",
|
||||||
|
"Type": "MSI",
|
||||||
|
"InstallArgs": "/qn /norestart REBOOT=ReallySuppress NOVSUI=1 USING_EXUIH_SILENT=1",
|
||||||
|
"DetectionMethod": "Registry",
|
||||||
|
"DetectionPath": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{A749D8E6-B613-3BE3-8F5F-045C84EBA29B}",
|
||||||
|
"PCTypes": ["*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_comment": "VC++ 2013 x64 Additional Runtime - required by Keyence VR-6000 Series Software. Pairs with the Minimum Runtime above.",
|
||||||
|
"Name": "VC++ Redistributable 2013 x64 (Additional)",
|
||||||
|
"Installer": "vcredist/2013-x64-add/installer.msi",
|
||||||
|
"Type": "MSI",
|
||||||
|
"InstallArgs": "/qn /norestart REBOOT=ReallySuppress NOVSUI=1 USING_EXUIH_SILENT=1",
|
||||||
|
"DetectionMethod": "Registry",
|
||||||
|
"DetectionPath": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{929FBD26-9020-399B-9A7A-751D61F0B942}",
|
||||||
|
"PCTypes": ["*"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"_comment": "VC++ 2010 x64 - required by PC-DMIS 2016/2019 R2 on CMM PCs. PCDLRN.exe links against msvcr100.dll and the VS 2010 MFC DLLs which are only provided by this redistributable. Extracted from the PC-DMIS 2016 bundle's attached container (a1 payload). Silent install: /q /norestart. Detection: Uninstall key under the native x64 hive with fixed product GUID.",
|
"_comment": "VC++ 2010 x64 - required by PC-DMIS 2016/2019 R2 on CMM PCs. PCDLRN.exe links against msvcr100.dll and the VS 2010 MFC DLLs which are only provided by this redistributable. Extracted from the PC-DMIS 2016 bundle's attached container (a1 payload). Silent install: /q /norestart. Detection: Uninstall key under the native x64 hive with fixed product GUID.",
|
||||||
"Name": "VC++ Redistributable 2010 x64",
|
"Name": "VC++ Redistributable 2010 x64",
|
||||||
|
|||||||
@@ -1,12 +1,140 @@
|
|||||||
# 09-Setup-Keyence.ps1 - Keyence-specific setup (runs after Shopfloor baseline)
|
# 09-Setup-Keyence.ps1 - Keyence type setup (runs during shopfloor-setup phase).
|
||||||
#
|
#
|
||||||
# PLACEHOLDER: add type-specific app installs when details are finalized.
|
# Installs the VR-6000 Series Software MSI and the KEYENCE VR Series USB driver
|
||||||
# This script will be called by Run-ShopfloorSetup.ps1 as part of the
|
# package. Both payloads ship inside this directory (shopfloor-setup\Keyence\)
|
||||||
# type-specific phase, after all baseline scripts have completed.
|
# and are staged by startnet.cmd during WinPE, so they exist locally on disk
|
||||||
|
# when this script runs - no share mapping required.
|
||||||
#
|
#
|
||||||
# For share-based installs, copy the pattern from CMM/09-Setup-CMM.ps1
|
# Layout (sibling to this .ps1):
|
||||||
# (credential lookup + share mount + install from share).
|
# installers\VR-6000 Series Software.msi
|
||||||
|
# drivers\keyence_vr_series.inf
|
||||||
|
# drivers\KEYENCE_VR_SERIES.cat
|
||||||
|
# drivers\amd64\WdfCoInstaller01009.dll
|
||||||
|
# drivers\amd64\WinUsbCoinstaller2.dll
|
||||||
|
#
|
||||||
|
# Prereqs (installed earlier by 00-PreInstall-MachineApps.ps1 via preinstall.json):
|
||||||
|
# - Microsoft Visual C++ 2010 x86 + x64
|
||||||
|
# - Microsoft Visual C++ 2013 x86 + x64 (Min + Add)
|
||||||
|
# - Microsoft Visual C++ 2017/2022 x86 (UCRT covers 2015-2022)
|
||||||
|
#
|
||||||
|
# Idempotent: skips the MSI if the product GUID is already registered, skips
|
||||||
|
# the driver if the package is already in the DriverStore.
|
||||||
|
#
|
||||||
|
# Log: C:\Logs\Keyence\09-Setup-Keyence.log
|
||||||
|
|
||||||
Write-Host "=== Keyence Setup ==="
|
$ErrorActionPreference = 'Continue'
|
||||||
Write-Host " (no type-specific apps configured yet)"
|
|
||||||
Write-Host "=== Keyence Setup Complete ==="
|
$logDir = 'C:\Logs\Keyence'
|
||||||
|
$transcriptLog = Join-Path $logDir '09-Setup-Keyence.log'
|
||||||
|
|
||||||
|
$installerDir = Join-Path $PSScriptRoot 'installers'
|
||||||
|
$msiPath = Join-Path $installerDir 'VR-6000 Series Software.msi'
|
||||||
|
$msiLog = Join-Path $logDir 'VR-6000-msiexec.log'
|
||||||
|
$driverDir = Join-Path $PSScriptRoot 'drivers'
|
||||||
|
$driverInf = Join-Path $driverDir 'keyence_vr_series.inf'
|
||||||
|
|
||||||
|
# Product registration - ProductCode read from the MSI via msiinfo: must match
|
||||||
|
# the value baked in, so idempotency works after a successful install.
|
||||||
|
$productCode = '{058E7194-BDF8-4FA2-9D69-978BB0F25214}'
|
||||||
|
$expectedVersion = '4.3.7'
|
||||||
|
$uninstallRegPaths = @(
|
||||||
|
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$productCode",
|
||||||
|
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$productCode"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (-not (Test-Path $logDir)) {
|
||||||
|
New-Item -Path $logDir -ItemType Directory -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
try { Start-Transcript -Path $transcriptLog -Append -Force | Out-Null } catch {}
|
||||||
|
|
||||||
|
function Write-KeyenceLog {
|
||||||
|
param([string]$Message, [string]$Level = 'INFO')
|
||||||
|
$stamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
|
Write-Host "[$stamp] [$Level] $Message"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-KeyenceLog "================================================================"
|
||||||
|
Write-KeyenceLog "=== Keyence Setup session start (PID $PID) ==="
|
||||||
|
Write-KeyenceLog "Running as: $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)"
|
||||||
|
Write-KeyenceLog "Script root: $PSScriptRoot"
|
||||||
|
Write-KeyenceLog "================================================================"
|
||||||
|
|
||||||
|
# --- Detection: skip MSI if already installed at expected version ---
|
||||||
|
$msiAlreadyInstalled = $false
|
||||||
|
foreach ($regPath in $uninstallRegPaths) {
|
||||||
|
if (Test-Path $regPath) {
|
||||||
|
$installed = (Get-ItemProperty $regPath -ErrorAction SilentlyContinue).DisplayVersion
|
||||||
|
if ($installed -eq $expectedVersion) {
|
||||||
|
Write-KeyenceLog "MSI already installed (DisplayVersion=$installed at $regPath) - skipping"
|
||||||
|
$msiAlreadyInstalled = $true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
Write-KeyenceLog "MSI registered but at version '$installed' (expected $expectedVersion) - will reinstall" "WARN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Install MSI ---
|
||||||
|
if (-not $msiAlreadyInstalled) {
|
||||||
|
if (-not (Test-Path $msiPath)) {
|
||||||
|
Write-KeyenceLog "MSI not found at $msiPath - aborting MSI install" "ERROR"
|
||||||
|
} else {
|
||||||
|
$msiSize = [math]::Round((Get-Item $msiPath).Length / 1MB, 1)
|
||||||
|
Write-KeyenceLog "Installing VR-6000 Series Software MSI ($msiSize MB)"
|
||||||
|
$msiArgs = @(
|
||||||
|
'/i', "`"$msiPath`"",
|
||||||
|
'/qn', '/norestart',
|
||||||
|
'ALLUSERS=1', 'REBOOT=ReallySuppress',
|
||||||
|
'/L*v', "`"$msiLog`""
|
||||||
|
)
|
||||||
|
$sw = [Diagnostics.Stopwatch]::StartNew()
|
||||||
|
$proc = Start-Process -FilePath 'msiexec.exe' -ArgumentList $msiArgs -Wait -PassThru -NoNewWindow
|
||||||
|
$sw.Stop()
|
||||||
|
# msiexec exit codes we tolerate: 0 = success, 3010 = success w/ reboot recommended
|
||||||
|
if ($proc.ExitCode -eq 0 -or $proc.ExitCode -eq 3010) {
|
||||||
|
Write-KeyenceLog "MSI install succeeded (exit=$($proc.ExitCode), elapsed=$([int]$sw.Elapsed.TotalSeconds)s)"
|
||||||
|
} else {
|
||||||
|
Write-KeyenceLog "MSI install FAILED (exit=$($proc.ExitCode)). See $msiLog" "ERROR"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Detection: skip driver if already in DriverStore ---
|
||||||
|
$driverAlreadyStaged = $false
|
||||||
|
try {
|
||||||
|
$pnpOut = & pnputil.exe /enum-drivers 2>&1 | Out-String
|
||||||
|
if ($pnpOut -match 'keyence_vr_series\.inf') {
|
||||||
|
Write-KeyenceLog "Keyence USB driver already in DriverStore - skipping"
|
||||||
|
$driverAlreadyStaged = $true
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-KeyenceLog "pnputil /enum-drivers failed ($($_.Exception.Message)); attempting install anyway" "WARN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Install driver ---
|
||||||
|
if (-not $driverAlreadyStaged) {
|
||||||
|
if (-not (Test-Path $driverInf)) {
|
||||||
|
Write-KeyenceLog "Driver INF not found at $driverInf - aborting driver install" "ERROR"
|
||||||
|
} else {
|
||||||
|
Write-KeyenceLog "Adding KEYENCE VR Series USB driver to DriverStore via pnputil"
|
||||||
|
$pnp = Start-Process -FilePath 'pnputil.exe' `
|
||||||
|
-ArgumentList '/add-driver', "`"$driverInf`"", '/install' `
|
||||||
|
-Wait -PassThru -NoNewWindow `
|
||||||
|
-RedirectStandardOutput (Join-Path $logDir 'pnputil-stdout.log') `
|
||||||
|
-RedirectStandardError (Join-Path $logDir 'pnputil-stderr.log')
|
||||||
|
# pnputil exit codes: 0 = ok, 3010 = ok (reboot recommended),
|
||||||
|
# 259 = ERROR_NO_MORE_ITEMS (no INFs matched)
|
||||||
|
if ($pnp.ExitCode -eq 0 -or $pnp.ExitCode -eq 3010) {
|
||||||
|
Write-KeyenceLog "Driver install succeeded (exit=$($pnp.ExitCode))"
|
||||||
|
} else {
|
||||||
|
Write-KeyenceLog "Driver install FAILED (exit=$($pnp.ExitCode))" "ERROR"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-KeyenceLog "================================================================"
|
||||||
|
Write-KeyenceLog "=== Keyence Setup session end ==="
|
||||||
|
Write-KeyenceLog "================================================================"
|
||||||
|
|
||||||
|
try { Stop-Transcript | Out-Null } catch {}
|
||||||
|
|||||||
BIN
playbook/shopfloor-setup/Keyence/drivers/KEYENCE_VR_SERIES.cat
Normal file
BIN
playbook/shopfloor-setup/Keyence/drivers/KEYENCE_VR_SERIES.cat
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,94 @@
|
|||||||
|
[Version]
|
||||||
|
Signature = "$Windows NT$"
|
||||||
|
DriverPackageDisplayName=%DESC%
|
||||||
|
Class = KeyenceUSB
|
||||||
|
ClassGuid={EE304F37-F588-45FC-91FE-B76873981AD1}
|
||||||
|
Provider = %ProviderName%
|
||||||
|
CatalogFile=KEYENCE_VR_SERIES.cat
|
||||||
|
DriverVer=03/26/2020,1.0.0.0
|
||||||
|
|
||||||
|
; ================== Class section ==================
|
||||||
|
|
||||||
|
[ClassInstall32]
|
||||||
|
Addreg=KeyenceClassReg
|
||||||
|
|
||||||
|
[KeyenceClassReg]
|
||||||
|
HKR,,,0,%ClassName%
|
||||||
|
HKR,,Icon,,-5
|
||||||
|
|
||||||
|
; ========== Manufacturer/Models sections ===========
|
||||||
|
|
||||||
|
[Manufacturer]
|
||||||
|
%ProviderName% = KEYENCE,NTamd64
|
||||||
|
|
||||||
|
[KEYENCE.NTamd64]
|
||||||
|
%USB\KeyenceDevice.DeviceDesc% =USB_Install,USB\VID_0720&PID_102C
|
||||||
|
|
||||||
|
; =================== Installation ===================
|
||||||
|
|
||||||
|
;[1]
|
||||||
|
[USB_Install]
|
||||||
|
Include=winusb.inf
|
||||||
|
Needs=WINUSB.NT
|
||||||
|
|
||||||
|
;[2]
|
||||||
|
[USB_Install.Services]
|
||||||
|
Include=winusb.inf
|
||||||
|
AddService=WinUSB,0x00000002,WinUSB_ServiceInstall
|
||||||
|
|
||||||
|
;[3]
|
||||||
|
[WinUSB_ServiceInstall]
|
||||||
|
DisplayName = %WinUSB_SvcDesc%
|
||||||
|
ServiceType = 1
|
||||||
|
StartType = 3
|
||||||
|
ErrorControl = 1
|
||||||
|
ServiceBinary = %12%\WinUSB.sys
|
||||||
|
|
||||||
|
;[4]
|
||||||
|
[USB_Install.Wdf]
|
||||||
|
KmdfService=WINUSB, WinUsb_Install
|
||||||
|
|
||||||
|
[WinUSB_Install]
|
||||||
|
KmdfLibraryVersion=1.9
|
||||||
|
|
||||||
|
;[5]
|
||||||
|
[USB_Install.HW]
|
||||||
|
AddReg=Dev_AddReg
|
||||||
|
|
||||||
|
[Dev_AddReg]
|
||||||
|
HKR,,DeviceInterfaceGUIDs,0x10000,"{B708995F-18C9-4D52-8D29-41FF2BFBF215}"
|
||||||
|
|
||||||
|
;[6]
|
||||||
|
[USB_Install.CoInstallers]
|
||||||
|
AddReg=CoInstallers_AddReg
|
||||||
|
CopyFiles=CoInstallers_CopyFiles
|
||||||
|
|
||||||
|
[CoInstallers_AddReg]
|
||||||
|
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUsbCoinstaller2.dll"
|
||||||
|
|
||||||
|
[CoInstallers_CopyFiles]
|
||||||
|
WdfCoInstaller01009.dll
|
||||||
|
WinUsbCoinstaller2.dll
|
||||||
|
|
||||||
|
[DestinationDirs]
|
||||||
|
CoInstallers_CopyFiles=11
|
||||||
|
|
||||||
|
; ================= Source Media Section =====================
|
||||||
|
;[7]
|
||||||
|
|
||||||
|
[SourceDisksNames]
|
||||||
|
1 = %DISK_NAME%,,,\amd64
|
||||||
|
|
||||||
|
[SourceDisksFiles.amd64]
|
||||||
|
WinUSBCoInstaller2.dll=1
|
||||||
|
WdfCoInstaller01009.dll=1
|
||||||
|
|
||||||
|
; =================== Strings ===================
|
||||||
|
|
||||||
|
[Strings]
|
||||||
|
ProviderName="KEYENCE"
|
||||||
|
DESC="VR Series USB-Driver"
|
||||||
|
WinUSB_SvcDesc="WinUSB.sys : KEYENCE USB Device"
|
||||||
|
DISK_NAME="KEYENCE USB Driver Installation Disk"
|
||||||
|
ClassName="KEYENCE USB Device Class"
|
||||||
|
USB\KeyenceDevice.DeviceDesc="VR Series"
|
||||||
Binary file not shown.
Reference in New Issue
Block a user