#JNA change windows 10 wallpaper

1 messages Β· Page 1 of 1 (latest)

winter ferry
#

I have a problem when i try to change the wallpaper of my windows 10 desktop to a image in my project folder. When i execute my code my desktop gets just a black-screen instate of my image. Here is the code of the Main Class(Core): ```Java
public class Core {

public void setWallpaper(String path) {
    User32.INSTANCE.SystemParametersInfoA(0x0014, 0, path, 0x0001 | 0x0002);
}

public String getAbsolutePath(String relativePath){
    URL imageURL = getClass().getResource(relativePath);
    File imageFile = new File(imageURL.getPath());

    return imageFile.getAbsolutePath();
}

public Core(){
    setWallpaper(getAbsolutePath("wallpapers/BillCipher.jpg"));
}

public static void main(String[] args) throws Exception {
    new Core();
}

And here is the Interface with the JNA stuff to declare the action:Java
public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
boolean SystemParametersInfoA(int uiAction, int uiParam, String pvParam, int fWinIni);
}```

timber geodeBOT
#

<@&987246452180930620> please have a look, thanks.

timber geodeBOT
#

While you are waiting for getting help, here are some tips to improve your experience:

Code is much easier to read if posted with syntax highlighting and proper formatting.

If nobody is calling back, that usually means that your question was not well asked and hence nobody feels confident enough answering. Try to use your time to elaborate, provide details, context, more code, examples and maybe some screenshots. With enough info, someone knows the answer for sure.

Don't forget to close your thread using the command </help-thread close:1027500463647621170> when your question has been answered, thanks.

timber geodeBOT
#

Closed the thread due to inactivity.

If your question was not resolved yet, feel free to just post a message to reopen it, or create a new thread. But try to improve the quality of your question to make it easier to help you πŸ‘

winter ferry
#

This message is for reopening this Thread and hoping for help

storm crag
#

I'll play around with this later today and get back to you if nobody else does

winter ferry
#

This problem is prob some very deep sh*t because my code is right and i readed the whole windows assembly parameters how they work. I gave the right parameter to set the wallpaper and this boolean even return true that the call was successful but the wallpaper is just not set and my old wallpaper got to a blackscreen

#

And my .jpg format is windows supported as well

#

tryed with png too

#

The only reason i found is this: ```In Windows 10, WM_SETTINGCHANGE processes Windows Explorer notifications generated as a result of changes to a monitor's workspace by recalculating the workspace for all monitors connected to the system. This recalculation takes into account the size and position of the taskbar window on the monitor as well as any app bars on the monitor registered by applications calling the SHAppBarMessage function. Changes to the workspace made by applications calling the SystemParametersInfo function are not taken into account, and this is intentional behavior.

The recalculation of the workspace by Windows Explorer can override changes made by an application to a monitor workspace while Windows Explorer is running. Applications that rely on changing the workspace may not function properly in Windows 10.``` but if thats the reason i have tbh no clue how to fix that

#

So basicly its a Windows 10 limitation

#

and i need now a way around it which sucks

storm crag
#

what OS are you on?

winter ferry
#

Windows 10

fluid plume
#

@winter ferry did you try to move the wallpaper out of resources ?

fluid plume
winter ferry
#

It do no difference

#

And i mean why would it even do a difference

fluid plume
#

which path are you using after that ?

winter ferry
#

i always get a new absolute path out of the relative path

#
public String getAbsolutePath(String relativePath){
        URL imageURL = getClass().getResource(relativePath);
        File imageFile = new File(imageURL.getPath());

        return imageFile.getAbsolutePath();
    }
#

So its not the problem with the path or format or anything else

fluid plume
#

no

#

just get the path directly

winter ferry
#

its just because of this function limitation of windows 10, so i need to find a work around

fluid plume
#

this is not supposed to work

winter ferry
winter ferry
#

if it would have a problem with the path then this windows function would return false, but it did return true

fluid plume
#

you are not supposed to do any path operation on anything located in resources

#

even if it works now

#

please change it

#

it's a coincidence if this return the correct path

winter ferry
fluid plume
winter ferry
#

but its still not the current problem i have

fluid plume
#

also

#

what is the format of your image

winter ferry
#

Im sorry if it sounds rude what i said or some but i can directly paste the right absolute path inside of the windows function but it just not helps me with my problem

fluid plume
#

is it bmp ?

winter ferry
fluid plume
#

ah

#

convert it

winter ferry
#

Converted and bmp not work as well which is not a big surprize because windows supports: jpg, png, bmp and tiff. So as i said jpg is not the problem

#

Im currently just trying to build way around without using SystemParametersInfoA because that function windows 10 do not support anymore when called by a application

storm crag
#

Your params are correct for SystemParametersInfoA from what I can see

#

but the latest JNA doesn't have that function

#

Also, not sure if we need to pass the values like this:

#
UINT uiAction = new UINT(0x0014);
UINT uiParam = new UINT(0);
#

The hard coding of SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE is also fine

winter ferry
#

but its also still fine, i mean the function gets still called

storm crag
#
    implementation 'net.java.dev.jna:jna:5.13.0'
    implementation 'net.java.dev.jna:jna-jpms:5.13.0'
    implementation 'net.java.dev.jna:jna-platform:5.13.0'
    implementation 'net.java.dev.jna:jna-platform-jpms:5.13.0'
#

that's in my build.gradle

winter ferry
#
dependencies {
    implementation 'net.java.dev.jna:jna:5.13.0'
}``` thats my build
storm crag
#

How are you resolving your imports?

#

I tried that at first but a lot of the classes I needed were missing

#

u didn't show imports in your snippet 😦

winter ferry
#
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface User32 extends StdCallLibrary {
    User32 INSTANCE = (User32) Native.load("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
    boolean SystemParametersInfoA(int uiAction, int uiParam, String pvParam, int fWinIni);
}```
storm crag
#
String filePath = "path/to/your/image.jpg";
BufferedImage image = ImageIO.read(new File(filePath));
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRect = new Rectangle(screenSize);
Image scaledImage = image.getScaledInstance(screenRect.width, screenRect.height, Image.SCALE_SMOOTH);
BufferedImage wallpaper = new BufferedImage(screenRect.width, screenRect.height, BufferedImage.TYPE_INT_RGB);
Graphics g = wallpaper.getGraphics();
g.drawImage(scaledImage, 0, 0, null);
g.dispose();
ImageIO.write(wallpaper, "jpg", new File("wallpaper.bmp"));
UINT uiAction = new UINT(0x0014);
UINT uiParam = new UINT(0);
String lpvParam = "wallpaper.bmp";```
winter ferry
#

thats the only 3 imports i use

storm crag
#

this is what I'm currently working with, I think Ala is right, you need to convert to .bmp

winter ferry
#

what imports do you use?

#

i mean in the class not the build gradle

storm crag
#

cool - I have repro'd ur issue

winter ferry
storm crag
#

on Win11 getting black wallpaper

winter ferry
#

same on windows 10

#

As i did read from the windows docs this function we currently used only worked on the lower versions of windows, in windows 10 there might be some issues with other processes when using this function

#

Im currently searching for other functions and i found one, trying to build it in my project but its way more complex and i will need some time

storm crag
#

Fixed itr

#
User32 INSTANCE = Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
boolean SystemParametersInfo(int one, int two, String s, int three);
#

boolean result = User32.INSTANCE.SystemParametersInfo(0x0014, 0, filePath, 1);

#

this worked

#

Give it ago @winter ferry

#

full code:

#
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public class Main {
    public interface User32 extends StdCallLibrary {
        User32 INSTANCE = Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
        boolean SystemParametersInfo(int one, int two, String s, int three);
    }

    public Main() throws Exception {
        String filePath = "path-to-bmp";
        boolean result = User32.INSTANCE.SystemParametersInfo(0x0014, 0, filePath, 1);
        if (result) {
            System.out.println("Success");
        } else {
            System.out.println("Failure");
        }
    }

    public static void main(String[] args) throws Exception {
        new Main();
    }
}
winter ferry
#

what did you changed?

storm crag
#

0x0001 | 0x0002

#

and

#

SystemParametersInfo

#

not using SystemParametersInfoA

winter ferry
#

And i just did such a complex thing but the solution was so much easyer xd

storm crag
#

I ended up finding the solution from a C++ post on SO

winter ferry
storm crag
#

Really?

winter ferry
#

yep

storm crag
#

Interesting, it worked for me on Windows 11

#

Is your image a .BMP?

winter ferry
storm crag
#

And try using the absolute path, I had the image saved to my Desktop

#

So try hard coding the full path

#

e.g. "C:\\User\\Desktop\\image.bmp" or whatever

winter ferry
#

i did hard coded the path and its still not working

#

i think there are always small differences between windows versions

storm crag
#

I need a Windows 10 license to change my vm's wallpaper

#

But I don't think there should be a difference in the versions for this specific functionality since all the examples are win10 ones anyway

winter ferry
storm crag
#

Sure but the "solution" was me copying the params he used lol

#

And he did say it worked fine πŸ˜‚

#

Post from 7 years ago

winter ferry
#

Checked a C# solution and that one did not work as well, this is such a scam ngl

storm crag
#

Are there any image constraints?

#

Like does it need to match your monitor etc?

#

In my other code, I resized the image

winter ferry
fallow jacinth
#

What's your path value?

winter ferry
#

"C:\Users\Mr.Mystery%201.0\Desktop\WallpaperChanger\build\resources\main\wallpapers\BillCipher.bmp"

#

I just hard coded it for now

#

I fixed it just now i found the issue and this issue sucks that its really the issue

#

because my user name have a space it was confusing the path, so i removed the space from my user name and it works now

#

im so happy that it work now

#

A lot of thanks for everyone who helped! peepo_heart

timber geodeBOT
#

Closed the thread.

fluid plume
#

I managed to do it with FFMA πŸ‘€

winter ferry
#

weird flex

storm crag
fluid plume
#
Linker linker = Linker.nativeLinker();
try(MemorySession session = MemorySession.openConfined()){
    SymbolLookup user32 = SymbolLookup.libraryLookup("user32", session);
    MemorySegment sysParamAddress = user32.lookup("SystemParametersInfoA").orElseThrow();
    var funDes = FunctionDescriptor.of(ValueLayout.JAVA_BOOLEAN, ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_INT);
    MethodHandle sysParam = linker.downcallHandle(sysParamAddress, funDes);
    MemorySegment cStringPath = session.allocateUtf8String("absolute_path");
    boolean result = (boolean) sysParam.invoke(0x0014, 0, cStringPath, 0x001 | 0x002);
    println(result);
}

@storm crag @winter ferry
If you ever want to do it with this new API which is currently available in preview in java 19, and you don't need any external lib.

storm crag
#

That is very interesting!

#

Thanks for the share ala

fluid plume
#

πŸ‘

#

now I have to turn my wallpaper back

winter ferry
fluid plume
#

And you wont guess what my wallpaper I set with this command

fluid plume
winter ferry
#

I wanted to do Java 17 for this project but then i did Java 8 because of one important thing but i forgot what was that important for me NootLikeThis

storm crag
#

Is it cleaned up at all by java? Or at least when the try block exists?

winter ferry
#

yeah i prob should at least before i not remember that important thing

fluid plume
storm crag
#

So if we don't call close, it'll be there forever?

fluid plume
#

yes

#

until the process stops

winter ferry
fluid plume
#

(like any C process)

storm crag
#

Ah okay

winter ferry
#

I mean with the lib its 3 lines of code the interface and 1 line to call it

fluid plume
# winter ferry But tbh i think the solution with the external lib looks cleaner ngl

The idea of this new lib is to replace JNI and many Unsafe methods basically (and so JNA)
The advantages are that it is safer, and it is fully controlled from java, like you directly use objects without any magic instead of the way jna works
Also note that libs may exist in the future allowing to simplify this, and there is already an existing tool that can generate such code automatically

storm crag
#

I would love a jna library that is just a wrapper over all those native api's

#

So you can call functions as you would any other way

#

Win32.systemBlah(param);

#

Or whatever

#

Followed by additional helper functions "changeWallpaper"

fluid plume
#

mhhhh

#

I'll make a question for jextract