You are here

SystemParametersInfo

12 posts / 0 new
Last post
englishman
Offline
Last seen: 11 years 3 months ago
Joined: 2010-02-03 11:10
SystemParametersInfo

Does anyone know how I can code a system call within the 2.0 launcher/code? Basically I need to refresh the desktop once the launched application has closed - in order to reset the original desktop. I thought that RefreshShellIcons might be enough, but this obviously doesn't seem to refresh the desktop. Without it, the desktop only reverts to its original state on the next windows logon.

Can someone please point me in the right direction? I know that other PA applications do this kind of thing with a call to SystemParametersInfo, but I cannot see how I can implement the required code within PA launcher ini.

Any links, pointers, advice etc. would be appreciated.

Thanks

Chris Morgan
Chris Morgan's picture
Offline
Last seen: 9 years 6 months ago
Joined: 2007-04-15 21:08
?

Could you please explain more about what the actual problem is that you're experiencing? I don't want to answer your question at present as I'm not at all convinced you're trying to do the right thing.

I am a Christian and a developer and moderator here.

“A soft answer turns away wrath, but a harsh word stirs up anger.” – Proverbs 15:1

englishman
Offline
Last seen: 11 years 3 months ago
Joined: 2010-02-03 11:10
OK...

I am making a wrapper for an existing freeware application that switches the desktop wallpaper. I know the application is portable, as I have been successfully using it for several months on various laptops and versions of windows via a DOS batch file script that copies files, edits pathnames in settings files etc. The author is aware of this, and has helpfully offered advice about environment variables, etc.

But I wanted to learn how to make a PortableApp (this is my first one), so it's is as much about me learning the process (than possibly making an application that with the authors permission could be made an official app).

In the DOS script, to refresh the desktop back to it's original state you can call the base application a second time via a commandline switch specifying the stored original wallpaper file name. This one-time run of the base application refreshes the desktop automatically back to it's original state. (As an aside, this could possibly be an alternative way of refreshing the desktop back to it's original state with PA, but there doesn't seem to be a way of doing this via PAL).

So, I am trying to workout how to do this refresh. It's early days, but the PA wrapper I have built seems to more or less work for me, apart from this final reversion. Logging out or switching the user in Windows then going back in to the user reverts the wallpaper back to it's original state - but ideally I need to work out how I can do this when closing the application.

Hope this makes sense... thanks for any pointers or solutions you can offer.

Chris Morgan
Chris Morgan's picture
Offline
Last seen: 9 years 6 months ago
Joined: 2007-04-15 21:08
So am I correct in thinking

So am I correct in thinking that what you want is basically to run App\whatever\whatever.exe --fix-this-computer afterwards? If that's all, try this for size (Other\Source\PortableApps.comLauncherCustom.nsh for PAL 2.0 or App\AppInfo\Launcher\Custom.nsh for PAL 2.1 Beta 2 which I recommend):

${SegmentFile}

${SegmentPostPrimary}
    ExecWait `"$AppDirectory\whatever\whatever.exe" --fix-this-computer`
!macroend

In PAL 2.2 you will be able to do such things inside the launcher.ini file.

I am a Christian and a developer and moderator here.

“A soft answer turns away wrath, but a harsh word stirs up anger.” – Proverbs 15:1

englishman
Offline
Last seen: 11 years 3 months ago
Joined: 2010-02-03 11:10
Thanks very much. It worked first time.

Thanks very much. It worked first time.

I will need to customise the commandline string for the call so as to pickup the correct original file, but I shall have a dig around as I shall hopefully learn more that way.

I shall also follow your recommendation and upgrade to PAL 2.1 Beta 2

Thanks again Chris.

englishman
Offline
Last seen: 11 years 3 months ago
Joined: 2010-02-03 11:10
Unfortunately I spoke too soon...

Testing shows that with the custom code above, the local directories don't get deleted at end of run. Or rather it seems that when the first base program close occurs the local directories seem to be copied back to the USB and deleted, but then the local directory structures and some of the files appear again (presumably on the final program call via the code above).

I tried adding a couple entries to the launcher:

[DirectoriesCleanupForce]
1=%APPDATA%\software\app
2=%LOCALAPPDATA%\software\app

... but this still failed to clean up.

I'd welcome any ideas on how to get round this...

The error occurs using Launcher 2.1 Beta and the original custom code above. Without the custom code the files get moved back and deleted (but I am then back to the original problem).

Thanks.

Chris Morgan
Chris Morgan's picture
Offline
Last seen: 9 years 6 months ago
Joined: 2007-04-15 21:08
Order; 2.2

This indicates that they're being created again by the closing run. The executable gets run after the other things in the Post hook, so it's running after the things have been moved back. This isn't what you want in this case.

For the moment then unless you can do it directly by a DLL call, there's no supported way to do it with the PortableApps.com Launcher; in 2.2 there will be an extra hook PostExec which will make this sort of case work.

Don't use DirectoriesCleanupForce ever. It's not what you want. (And it'll be gone in probably 2.2.)

I am a Christian and a developer and moderator here.

“A soft answer turns away wrath, but a harsh word stirs up anger.” – Proverbs 15:1

englishman
Offline
Last seen: 11 years 3 months ago
Joined: 2010-02-03 11:10
OK... thanks, here's a further question...

Since the purpose of this additional call is to reset the desktop back to it's original state, then presumably, (going back to my original idea), using SystemParametersInfo after resetting the relevant registry keys back to their original values would avoid the need for an additional base program call. Something like...

${SegmentFile}
     
Var _Custom_OriginalWallpape
Var _Custom_OriginalWallpaperStyle
Var _Custom_OriginalTileWallpaper
Var _Custom_OriginalWallpaperOriginX
Var _Custom_OriginalWallpaperOriginY

${SegmentPrePrimary}
${Registry::Read} "HKCU\Control Panel\Desktop" Wallpaper $_Custom_OriginalWallpaper $R0
${Registry::Read} "HKCU\Control Panel\Desktop" WallpaperStyle $_Custom_OriginalWallpaperStyle $R0
${Registry::Read} "HKCU\Control Panel\Desktop" TileWallpaper $_Custom_OriginalTileWallpaper $R0
${Registry::Read} "HKCU\Control Panel\Desktop" WallpaperOriginX $_Custom_OriginalWallpaperOriginX $R0
${Registry::Read} "HKCU\Control Panel\Desktop" WallpaperOriginY $_Custom_OriginalWallpaperOriginY $R0
!macroend
     
${SegmentPostPrimary}
!define SPI_SETDESKWALLPAPER 20
!define SPIF_SENDWININICHANGE 0x0002
${Registry::Write} "HKCU\Control Panel\Desktop" Wallpaper $_Custom_OriginalWallpaper REG_SZ $R0
${Registry::Write} "HKCU\Control Panel\Desktop" WallpaperStyle $_Custom_OriginalWallpaperStyle REG_SZ $R0
${Registry::Write} "HKCU\Control Panel\Desktop" TileWallpaper $_Custom_OriginalTileWallpaper REG_SZ $R0
${Registry::Write} "HKCU\Control Panel\Desktop" WallpaperOriginX $_Custom_OriginalWallpaperOriginX REG_DWORD $R0
${Registry::Write} "HKCU\Control Panel\Desktop" WallpaperOriginY $_Custom_OriginalWallpaperOriginY REG_DWORD $R0
System::Call 'user32.dll::SystemParametersInfo(i ${SPI_SETDESKWALLPAPER}, i 0, t "$_Custom_OriginalWallpaper", i ${SPIF_SENDWININICHANGE}) i .r1'
!macroend

This seems to work, but I'm unsure whether there is a better way of doing this. I tried originally just to define HKCU\Control Panel\Desktop in the registry key section in the launcher (to discard changes) but it persistently crashes out on launch. Not sure why.

Grateful for any further advice on improving this.

Thanks

Chris Morgan
Chris Morgan's picture
Offline
Last seen: 9 years 6 months ago
Joined: 2007-04-15 21:08
Windows 7 changing backgrounds

I think you'd probably run across the same problem as has been encountered in the Platform with its background change feature - the background image slideshow feature of Windows 7 gets stopped. I believe John has a solution for this which will deploy in the next version of the Platform.

Try taking a look at the Platform source code after John releases the next beta/RC.

I am a Christian and a developer and moderator here.

“A soft answer turns away wrath, but a harsh word stirs up anger.” – Proverbs 15:1

englishman
Offline
Last seen: 11 years 3 months ago
Joined: 2010-02-03 11:10
You are right...

I thought I had that one sorted as I back up the files used by the theme/slideshow. On exit it restores the last themed picture but doesn't seem to advance. I shall have to look into this... thanks.

pfeerick
pfeerick's picture
Offline
Last seen: 8 years 7 months ago
Joined: 2005-12-13 19:21
These two options work with Windows 7

Once you've altered the wallpaper in the registry... the hard bit is waking Windows up and making it refresh... here are googled ways to kick it... both these methods work on Windows 7 Professional with no problems... then there's the NSIS way of setting and refreshing the wallpaper using the SystemParametersInfo call directly... also working with Windows 7 Smile

Method 1 - Courtesy of Torgeir Bakken, MVP.

Click Start, Run and type:

RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters

This command-line refreshes the desktop wallpaper (should be a .bmp file).

Method 2: Using a program that uses the "SystemParametersInfo" API call to
apply the desktop wallpaper dynamically. I wrote this program some time ago,
and you may use it if you're interested.

http://windowsxp.mvps.org/wprefresh.exe

Method 3: Complete NSIS Script - just change "D:\Wall.bmp" to a .bmp wallpaper you have...

OutFile "change wallpaper.exe"
RequestExecutionLevel user

Section ""
!define SPI_SETDESKWALLPAPER 0x0014
!define WALLPAPER "D:\Wall.bmp"
!define SPIF_UPDATEINIFILE 0x0001
!define SPIF_SENDWININICHANGE 0x0002

System::Alloc ${NSIS_MAX_STRLEN}
Pop $0
StrCpy $0 "${WALLPAPER}"

System::Call "user32::SystemParametersInfo(i ${SPI_SETDESKWALLPAPER}, i 0, t r0, i ${SPIF_SENDWININICHANGE}) i .r1"

System::Free $0
SectionEnd

englishman
Offline
Last seen: 11 years 3 months ago
Joined: 2010-02-03 11:10
Thank you!

I guess it would be best to stick to the NSIS coding solution if at all possible. Your solution above is pretty similar to what I had, but I will need to try and work out what the additional fields do. It seems for example that you set SPIF_UPDATEINIFILE to 0x0001 but actually don't use it in the call. I'm also not sure if I need to bother with the System:Alloc and System:: Free values in a script... presumably not. Thanks for the useful info!

Log in or register to post comments