Necesito saber cómo se obtiene la ruta de la imagen de fondo en windows 8.1 y si es posible en windows 10 también
OJO!!!!! cuando esta puesta una carpeta con varias imágenes que van cambiando cada cierto tiempo.
Las que vienen por defecto: C:\Windows\Web\Wallpaper\
Se obtienen buscándolas, por ejemplo un buen buscador de archivos es Everything de VoidTools: https://www.voidtools.com/ . Si mantienes el cursor del mouse sobre la imagen aparece su nombre con su extensión, luego solo buscas ese nombre en Everything, justo debe estar en el Disco C, carpeta igual al que muestra la pantalla de configuración de Fondos de Escritorio (Flores, Tierra, Windows, etc)
Parece que no me explique bien, yo me refiero a que en el registro de Windows en la clave
HKEY_CURRENT_USER\Control Panel\Desktop
en el valor Wallpaper aparece la ruta completa de la imagen de papel tapiz actual.
El problema es que cuando pongo una carpeta de imágenes para que cambie el papel tapiz cada cierto tiempo lo que aparece en ese valor del registro es
C:\Users\Usuario\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper
Y de esta manera no puedo obtener la ruta de la imagen actual y quisiera saber si existe algún método para obtener la ruta en este caso
Gracias
Pues esa misma es la ruta de la imagen actual: C:\Users\Usuario\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper
Solo que ese TranscodedWallpaper no tiene extensión pero si es la imagen actual que va creando y reemplazando el propio Windows cada cierto tiempo, dicho tiempo es especificado en la propia configuración de Fondo de Pantalla.
Puedes hacer la prueba copiándolo y renombrándolo con la extensión apropiada, ya sea .jpg o .png
Waooo, nunca se me hubiera ocurrido eso. Pero ese mecanismo solo empeora mi situación, ya que no obtengo la ruta de la imagen original, solo la de la copia que hace windows.
Lo que necesito es la ruta de la imagen original que ahora me parece más complejo de obtener
Gracias
Cita de: bybaal en 3 Febrero 2021, 04:28 AM
Lo que necesito es la ruta de la imagen original que ahora me parece más complejo de obtener
La ruta que deseas obtener puedes localizarla, codificada, en el valor de registro: 'HKEY_CURRENT_USER\Control Panel\Desktop' > 'TranscodedImageCache', en formato de texto Unicode (UTF-16).
He desarrollado un sencillo script en PowerShell / VB.NET que se puede iniciar por linea de comandos para obtener la ruta del wallpaper actual:
$vbCode = @'
Imports Microsoft.VisualBasic
Imports Microsoft.Win32
Imports System
Imports System.Security.AccessControl
Imports System.Text
Public NotInheritable Class WallpaperUtils
Public Shared Function GetCurrentWallpaperPath() As String
Using baseKey As RegistryKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default),
subKey As RegistryKey = baseKey.OpenSubKey("Control Panel\Desktop", RegistryRights.QueryValues)
' Main registry value
Const prefixByteSize As Integer = 24
Dim transcodedImageCache As Byte() = CType(subKey.GetValue("TranscodedImageCache"), Byte())
If (transcodedImageCache IsNot Nothing) AndAlso (transcodedImageCache.Length > prefixByteSize) Then
Dim pathRaw As String = Encoding.Unicode.GetString(transcodedImageCache)
Dim path As String = pathRaw.Substring(prefixByteSize \ 2).TrimEnd(ControlChars.NullChar)
If Not String.IsNullOrWhiteSpace(path) Then
Return path
End If
End If
' Alternative registry value
Dim wallpaper As String = CStr(subKey.GetValue("WallPaper"))
If Not String.IsNullOrWhiteSpace(wallpaper) Then
Return wallpaper
End If
End Using
Return Nothing
End Function
End Class
'@
$WallpaperUtilsType =
Add-Type -TypeDefinition $vbCode `
-CodeDomProvider (New-Object Microsoft.VisualBasic.VBCodeProvider) `
-PassThru `
-ReferencedAssemblies "Microsoft.VisualBasic.dll", `
"System.dll" `
| where { $_.IsPublic }
$wallpaperPath = [WallpaperUtils]::GetCurrentWallpaperPath()
Write-Host $wallpaperPath
$console = [System.Console]
$console::WriteLine("Press any key to exit...")
$console::ReadKey($true)
Exit(0)
(https://i.imgur.com/yWtvZ3h.png)
Esta parte puedes eliminarla completamente del script si lo prefieres:
$console = [System.Console]
$console::WriteLine("Press any key to exit...")
$console::ReadKey($true)
...de esta forma podrías iniciar el script de PowerShell desde un Batch-script o como desees para automatizar la obtención del valor de la ruta del wallpaper sin detener la ejecución del script.
PD: Esta metodología funcionará siempre y cuando el usuario no haya eliminado intencionada o involuntariamente los valores de registro 'TranscodedImageCache' y 'Wallpaper' después de haber aplicado el wallpaper, lo cual no debería suceder en ninguna circunstancia a menos que uno vaya al registro de Windows y los elimine intencionadamente como ya dije.
Saludos.
En vista de que por otros comentarios tuyos que vi en el foro al parecer utilizas VB.NET, te comento otras dos opciones utilizando directamente la API de Windows.
La primera es mediante una llamada a la función 'SystemParametersInfo' pasándole el valor 'SPI_GETDESKWALLPAPER' (0x0073) al parámetro 'uiAction':
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx)
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto, BestFitMapping:=False, ThrowOnUnmappableChar:=True)>
Public Shared Function SystemParametersInfo(action As UInteger,
uiParam As UInteger,
<[In]> <Out> pvParam As StringBuilder,
winIni As UInteger
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Modo de empleo:
Public Shared Function GetCurrentWallpaperPath() As String
Dim sb As New System.Text.StringBuilder(capacity:=260)
If Not NativeMethods.SystemParametersInfo(&H73UI, CUInt(sb.Capacity), sb, Nothing) Then
Throw New Win32Exception([error]:=Marshal.GetLastWin32Error())
Else
Return sb.ToString()
End If
End Function
La segunda es mediante la función 'GetWallpaper' de la interfaz 'IActiveDesktop':
https://msdn.microsoft.com/en-us/library/windows/desktop/bb776357%28v=vs.85%29.aspx (https://msdn.microsoft.com/en-us/library/windows/desktop/bb776357%28v=vs.85%29.aspx)
Imports System.Runtime.InteropServices
Imports System.Text
Namespace NativeMethods
<ComImport>
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
<Guid("F490EB00-1240-11D1-9888-006097DEACF9")>
Public Interface IActiveDesktop
Function NotImplemented01() As Integer
<PreserveSig()> Function GetWallpaper(<MarshalAs(UnmanagedType.LPWStr)> buffer As StringBuilder, bufferSize As Integer, reserved As Integer) As Integer
Function NotImplemented02() As Integer
Function NotImplemented03() As Integer
Function NotImplemented04() As Integer
Function NotImplemented05() As Integer
Function NotImplemented06() As Integer
Function NotImplemented07() As Integer
Function NotImplemented08() As Integer
Function NotImplemented09() As Integer
Function NotImplemented10() As Integer
Function NotImplemented11() As Integer
Function NotImplemented12() As Integer
Function NotImplemented13() As Integer
Function NotImplemented14() As Integer
Function NotImplemented15() As Integer
Function NotImplemented16() As Integer
Function NotImplemented17() As Integer
Function NotImplemented18() As Integer
End Interface
End Namespace
Modo de empleo:
Public Shared Function GetCurrentWallpaperPath() As String
Dim typeActiveDesktop As Type = Type.GetTypeFromCLSID(New Guid("{75048700-EF1F-11D0-9888-006097DEACF9}"))
Dim activeDesktop As IActiveDesktop = DirectCast(Activator.CreateInstance(typeActiveDesktop), IActiveDesktop)
Dim sb As New System.Text.StringBuilder(capacity:=260)
Dim result As Integer = activeDesktop.GetWallpaper(sb, sb.Capacity, 0)
If (result <> 0) Then
Marshal.ThrowExceptionForHR(result)
End If
Marshal.ReleaseComObject(activeDesktop)
Return sb.ToString()
End Function