Does anyone know how to change the lock screen via pascal? lazarus / 34-Windows ---------------------------------------------------------------------- vonskie · 2017-08-21 13:59 I have a program that changes the wallpaper at set intervals I would also like to change the lock screen ---------------------------------------------------------------------- Thaddy · 2017-08-21 14:02 Quote from: vonskie on August 21, 2017, 03:59:17 pmI have a program that changes the wallpaper at set intervals I would also like to change the lock screen You probably need a service to do that. Code will be similar. ---------------------------------------------------------------------- vonskie · 2017-08-21 14:21 I can not find an example of the code to change the lock screen via pascal anywhere ---------------------------------------------------------------------- RAW · 2017-08-21 14:29 QuoteI can not find an example of the code to change the lock screen via pascal anywhere This is your chance !!! BE THE FIRST ONE ... ---------------------------------------------------------------------- rvk · 2017-08-21 14:45 Quote from: Thaddy on August 21, 2017, 04:02:18 pmQuote from: vonskie on August 21, 2017, 03:59:17 pmI have a program that changes the wallpaper at set intervals I would also like to change the lock screen You probably need a service to do that. Code will be similar. A service ??????? (not sure what a service has got to do with this) @vonskie, you've already asked that question: https://forum.lazarus.freepascal.org/index.php?topic=35921.0 I don't think it can be done with the windows api. I think you'll need the .NET framework to set the Windows.System.UserProfile.LockScreen.SetImageFileAsync() like you mentioned in that thread. SystemParametersInfo(SPI_SETDESKWALLPAPER... (what you're probably using now) only works for the desktop image. You could try tinkering with the registry. HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization \LockScreenImage Haven't tried it myself (I also think this will only change the default/new user lockscreen, not for existing users). (note that this could be different per Windows version) ---------------------------------------------------------------------- Thaddy · 2017-08-21 14:51 It can be done with the winapi and it will probably  work best as a service. (because of multiple users on same pc) I found some c++ examples ---------------------------------------------------------------------- rvk · 2017-08-21 14:53 Quote from: Thaddy on August 21, 2017, 04:51:55 pmIt can be done with the winapi and it will probably  work best as a service. (because of multiple users on same pc) I found some c++ examples Did you find c++ examples for winapi win32? Or for .NET ?? (I think the Windows.System.UserProfile.LockScreen.SetImageFileAsync() are .NET examples) ---------------------------------------------------------------------- vonskie · 2017-09-11 16:32 Here is what I came up with by researching online, the problem is I get an access denied when trying to access the openkey. So I am stuck... Any other options? procedure TMyApplication.setlockscreen(slockscreenPath: string; version:integer);   var     reg: TRegistry;   begin     try       try         reg := TRegistry.Create;         reg.RootKey := hkey_local_machine;          if reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Aut hentication\LogonUI\Background', true) then         begin           reg.WriteInteger('OEMBackground', 1);         end         else writeln(reg.LastErrorMsg);         if not (directoryexists(SystemFolder+'\oobe\info')) then createdir(SystemFolder+'\oobe\info');         if not (directoryexists(SystemFolder+'\oobe\info\backgrounds')) then createdir(SystemFolder+'\oobe\info\backgrounds');         if (fileexists(SystemFolder+'\oobe\info\backgrounds\background Default.jpg')) then deletefile(SystemFolder+'\oobe\info\backgrounds\ba ckgroundDefault.jpg');         copyfile(slockscreenPath, SystemFolder+'\oobe\info\backgrounds\backgroundDefault.jpg');         SysUtils.ExecuteProcess(UTF8ToSys('rundll32'),(UTF8ToSys('"USE R32.DLL,UpdatePerUserSystemParameters, 1, True"')), []);       finally         reg.Free;       end;     except       on E: Exception do         DumpExceptionCallStack(E, 'log');     end;   end; ---------------------------------------------------------------------- rvk · 2017-09-12 08:13 Quote from: vonskie on September 11, 2017, 06:32:20 pmHere is what I came up with by researching online, the problem is I get an access denied when trying to access the openkey. So I am stuck...First... you are trying to write to hkey_local_machine. Are you running this program "as administrator" ?? As normal user you don't have permission to write to hkey_local_machine. Second... you are trying to write a file to the systemfolder. Again, that is not allowed as normal user and requires elevation to administrator status. Third... are you sure the registrykey \oobe\info\backgrounds\backgroundDefault.jpg is for the "Lock screen". You state you wanted to change the lock screen. I think the registrykey you are referring to is for the Logon screen. Those are two different things. You can try running your program "as administrator" and see if that's what you want. ---------------------------------------------------------------------- Thaddy · 2017-09-12 09:16 Quote from: rvk on September 12, 2017, 10:13:35 amQuote from: vonskie on September 11, 2017, 06:32:20 pmHere is what I came up with by researching online, the problem is I get an access denied when trying to access the openkey. So I am stuck...First... you are trying to write to hkey_local_machine. Are you running this program "as administrator" ?? As normal user you don't have permission to write to hkey_local_machine. Second... you are trying to write a file to the systemfolder. Again, that is not allowed as normal user and requires elevation to administrator status. Third... are you sure the registrykey \oobe\info\backgrounds\backgroundDefault.jpg is for the "Lock screen". You state you wanted to change the lock screen. I think the registrykey you are referring to is for the Logon screen. Those are two different things. You can try running your program "as administrator" and see if that's what you want. That's why I wrote: a service.... And finally you came to the same conclusion.... Big case of not listening. ---------------------------------------------------------------------- rvk · 2017-09-12 09:24 Quote from: Thaddy on September 12, 2017, 11:16:36 amThat's why I wrote: a service.... And finally you came to the same conclusion.... Big case of not listening. Thaddy, you MISUNDERSTAND  For setting the global logon background you need administrator permission. For setting the personal user lock screen background you DON'T need administrator permission. So, it's just a question what the user wants and in the opening post and title the LOCK SCREEN background change was asked for. But you also still haven't showed code how to change the LOCK SCREEN background for the user  Just repeating you need a service doesn't help vonskie if (s)he doesn't know what code to use. ---------------------------------------------------------------------- vonskie · 2017-09-13 20:05 Here is what I came up with that works You will need elevated privileges to run it. procedure TForm1.setlockscreen(slockscreenPath: string); var   reg: TRegistry; begin   try     if (slockscreenPath = 'clear') then     begin       try         reg := TRegistry.Create(KEY_WRITE or KEY_WOW64_64KEY);         reg.Lazywrite := False;         reg.RootKey := hkey_local_machine;         if reg.OpenKey(           'SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Lo gonUI\Background', True) then         begin           reg.Writeinteger('OEMBackground', StrToInt('$00000000'));           SysUtils.ExecuteProcess(UTF8ToSys('rundll32'),             (UTF8ToSys('"USER32.DLL,UpdatePerUserSystemParameters, 1, True"')), []);           exit;         end;       finally         reg.Free;       end;     end;     try       reg := TRegistry.Create(KEY_WRITE or KEY_WOW64_64KEY);       reg.Lazywrite := False;       reg.RootKey := hkey_local_machine;       if reg.OpenKey(         'SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Logo nUI\Background', True) then       begin         reg.Writeinteger('OEMBackground', StrToInt('$00000001'));       end;       if not (directoryexists(windowsfolder + '\SysNative\oobe\info\backgrounds')) then         createdir(windowsfolder + '\SysNative\oobe\info\backgrounds');       if (fileexists(windowsfolder +         '\SysNative\oobe\info\backgrounds\backgroundDefault.jpg')) then       begin         deletefile(windowsfolder +           '\SysNative\oobe\info\backgrounds\backgroundDefault.jpg');       end;       copyfile(slockscreenPath,         windowsfolder + '\SysNative\oobe\info\backgrounds\backgroundDefault.jpg');       SysUtils.ExecuteProcess(UTF8ToSys('rundll32'),         (UTF8ToSys('"USER32.DLL,UpdatePerUserSystemParameters, 1, True"')), []);     finally       reg.Free;     end;   except     on E: Exception do       DumpExceptionCallStack(E);   end; end; ---------------------------------------------------------------------- ASerge · 2017-09-15 17:27 Quote from: vonskie on September 13, 2017, 10:05:54 pmHere is what I came up with that works 1. As indicated by @rvk, this is for the logon screen, not for the lock screen. 2. This only works in Windows 7. In Windows 8 and Windows 10, there are other ways. And, if I remember correctly, they also differ from Windows 8 and Windows 8.1. 3. Key SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication is shared (not redirected) - no need KEY_WOW64_64KEY. 4. Instead of calling UpdatePerUserSystemParameters by running an external program, use the direct call to SystemParametersInfo (or BroadcastSystemMessage with WM_SETTINGCHANGE). In my tests it is not necessary at all, the changes are immediately visible. 5. And again put the cart before the horse. Read carefully the documents about the try finally. I already posted several times about this on the forum.