Papel Tapiz con carpeta de imágenes

Iniciado por bybaal, 2 Febrero 2021, 21:26 PM

0 Miembros y 1 Visitante están viendo este tema.

bybaal

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.

EdePC

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)

bybaal

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

EdePC

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

bybaal

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

Mr. NoBody

#5
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:

Código (vbnet) [Seleccionar]
$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)




Esta parte puedes eliminarla completamente del script si lo prefieres:
Código (vb) [Seleccionar]
$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.

Mr. NoBody

#6
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
Código (vbnet) [Seleccionar]

<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:
Código (vbnet) [Seleccionar]
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
Código (vbnet) [Seleccionar]
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:
Código (vbnet) [Seleccionar]
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