我可以在Java/Groovy中以编程方式更改Windows桌面墙纸吗?

我可以在Java/Groovy中以编程方式更改Windows桌面墙纸吗?,java,groovy,Java,Groovy,有没有一种方法可以使用Java(或Groovy)在Windows XP中更改桌面壁纸?我有一个程序,每天(或任何时候)创建一个新的图像,我想要一种方法来自动更新我的桌面 我在这个网站上似乎有一些关于C++或.NET的问题,但是我没有看到任何对java有特殊性的东西。 JNA java库允许你轻松调用Win32 API调用。特别是,要更改桌面背景,需要调用该函数 看看这篇文章,了解JNA的介绍:您可以编写一个批处理文件,并使用 Runtime.getRuntime.exec()很抱歉,我有点落后

有没有一种方法可以使用Java(或Groovy)在Windows XP中更改桌面壁纸?我有一个程序,每天(或任何时候)创建一个新的图像,我想要一种方法来自动更新我的桌面


<>我在这个网站上似乎有一些关于C++或.NET的问题,但是我没有看到任何对java有特殊性的东西。

JNA java库允许你轻松调用Win32 API调用。特别是,要更改桌面背景,需要调用该函数

看看这篇文章,了解JNA的介绍:

您可以编写一个批处理文件,并使用


Runtime.getRuntime.exec()

很抱歉,我有点落后于@ataylor的答案,因为我正在准备一个代码片段来完成它。是的,JNA是一种正确的方法。给你:

import java.util.HashMap;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.win32.*;

public class WallpaperChanger {
   public static void main(String[] args) {
      //supply your own path instead of using this one
      String path = "C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg";

      SPI.INSTANCE.SystemParametersInfo(
          new UINT_PTR(SPI.SPI_SETDESKWALLPAPER), 
          new UINT_PTR(0), 
          path, 
          new UINT_PTR(SPI.SPIF_UPDATEINIFILE | SPI.SPIF_SENDWININICHANGE));
   }

   public interface SPI extends StdCallLibrary {

      //from MSDN article
      long SPI_SETDESKWALLPAPER = 20;
      long SPIF_UPDATEINIFILE = 0x01;
      long SPIF_SENDWININICHANGE = 0x02;

      SPI INSTANCE = (SPI) Native.loadLibrary("user32", SPI.class, new HashMap<Object, Object>() {
         {
            put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
            put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
         }
      });

      boolean SystemParametersInfo(
          UINT_PTR uiAction,
          UINT_PTR uiParam,
          String pvParam,
          UINT_PTR fWinIni
        );
  }
}
import java.util.HashMap;
导入com.sun.jna.Native;
导入com.sun.jna.platform.win32.WinDef.UINT\u PTR;
导入com.sun.jna.win32。*;
公共类壁纸转换器{
公共静态void main(字符串[]args){
//提供您自己的路径,而不是使用此路径
String path=“C:\\Users\\Public\\Pictures\\Sample Pictures\\jummy.jpg”;
SPI.INSTANCE.SystemParametersInfo(
新UINT_PTR(SPI.SPI_Setdesk壁纸),
新UINT_PTR(0),
路径
新UINT_PTR(SPI.SPIF_UPDATEINIFILE | SPI.SPIF_sendwinichange));
}
公共接口SPI扩展StdCallLibrary{
//来自MSDN文章
长SPI_SETDESKWALLPAPER=20;
长SPIF_UpdateInFile=0x01;
长SPIF_sendwinichange=0x02;
SPI实例=(SPI)Native.loadLibrary(“user32”,SPI.class,new HashMap()){
{
put(选项类型映射器,w32 pitypemapper.UNICODE);
put(选项函数映射器,W32APIFunctionMapper.UNICODE);
}
});
布尔系统参数信息(
行动,
UINT_PTR uiParam,
字符串pvParam,
乌恩图夫维尼尼酒店
);
}
}
您需要在类路径上有JNA库,这样才能工作。这是在Windows7中测试的,在XP中可能有一些细微差别,但我认为它应该可以工作。该API大概是稳定的

工具书类
编辑(2010/01/20): 我之前省略了选项
SPIF\u UPDATEINIFILE
SPIF\u sendwinichange
。现在正按照Coding4Fun MSDN文章中的建议使用这些工具。

您可以更轻松地做到:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.PVOID;
import com.sun.jna.win32.W32APIOptions;
public class Wallpaper {    
 public static interface User32 extends Library {
     User32 INSTANCE = (User32) Native.loadLibrary("user32",User32.class,W32APIOptions.DEFAULT_OPTIONS);        
     boolean SystemParametersInfo (int one, int two, String s ,int three);         
 }
public static void main(String[] args) {   
   User32.INSTANCE.SystemParametersInfo(0x0014, 0, "C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg" , 1);
   }
 }

这是一个纯Java实现,用于将本机回调生成Windows USER32.DLL。它需要JDK16版本才能运行,但不需要巴拿马早期访问构建

import java.lang.invoke.*;
import java.nio.file.Path;
import jdk.incubator.foreign.*;
/**
 %JDK16%\bin\java -Dforeign.restricted=permit --add-modules jdk.incubator.foreign -cp your.jar SetWallpaper A.JPG
 */
public static void main(String[] args) throws Throwable {
    LibraryLookup user32 = LibraryLookup.ofLibrary("user32");
    MethodHandle spi = CLinker.getInstance().downcallHandle(user32.lookup("SystemParametersInfoA").get()
        // BOOL SystemParametersInfoA         (UINT uiAction,  UINT uiParam,   PVOID pvParam,       UINT fWinIni);
        , MethodType.methodType(int.class,     int.class,      int.class,      MemoryAddress.class, int.class)
        , FunctionDescriptor.of(CLinker.C_LONG,CLinker.C_LONG, CLinker.C_LONG, CLinker.C_POINTER,   CLinker.C_LONG));

    final int SPI_SETDESKWALLPAPER  = 0x0014;
    final int SPIF_UPDATEINIFILE    = 0x01;
    final int SPIF_SENDCHANGE       = 0x02;

    Path path = Path.of(args[0]).toAbsolutePath();

    try (NativeScope scope = NativeScope.unboundedScope()) {
        MemorySegment img = CLinker.toCString(path.toString(), scope);
        int status = (int)spi.invokeExact(SPI_SETDESKWALLPAPER, 0, img.address(), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
        System.out.println("Changed wallpaper to "+path+" rc="+status);
    }
}

这很奇怪——我就是无法用这个(或任何其他方法)来设置Java中的墙纸。它看起来与MSDN示例完全一致。有趣的是,UINT_PTR导入不在我拥有的JNA版本中。编辑:我的问题是在将输出文件设置为墙纸之前没有关闭它@greynolds除了jna.jar之外,还需要下载platform.jar。那会有很多麻烦。你可以找到这两个版本的最新版本。我知道这是旧版本,但我得到了一个错误:
方法loadLibrary(String,Class,new HashMap(){})对于类型Native是未定义的
这使用的是什么JNA版本,如果早于4.1.0,我在哪里可以找到下载该版本的内容?@Scruffy,将HashMap类型从
new HashMap()更改为
新的HashMap
。而且,这不符合我的形象。这是一个可以设置桌面墙纸的C#命令行程序。作者最初创建它是为了从一个用。。。爪哇@亚历克斯:谢谢你的发帖。这对我来说非常有效,即使JNA示例中没有一个对我有效(尽管没有出现错误,也没有对墙纸进行任何更改…),这基本上是一个只有链接的答案。你们能在这个答案中添加一个批次以防链接中断吗?默认情况下,它可以处理上面提到的图像。但它不能处理我的图像,即使我的文件存在于给定的位置。