Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

Change windows profile icon tile


  • Please log in to reply
9 replies to this topic

#1 NDog

NDog

    Adventurer

  • Active Members
  • PipPip
  • 107 posts

Posted 17 April 2011 - 03:57 AM

Taken from Joco Blog

If you compile this with .NET v2.0.50727 it generates an exe that can be used to change windows user profile icon tile by using command line.

syntax
tile_replace.exe "username" "pathtobmp"
eg
tile_replace.exe "ndog" "C:\ProgramData\Microsoft\User Account Pictures\Default Pictures\usertile12.bmp"


I would like to convert to this autoit 3, so no .NET framework overhead needed. Any ideas?

c:\Tile_replace.cs
using System; using System.Runtime.InteropServices; namespace FejesJoco {     class Program     {         [DllImport("shell32.dll", EntryPoint = "#262", CharSet = CharSet.Unicode, PreserveSig = false)]         public static extern void SetUserTile(string username, int whatever, string picpath);         [STAThread]         static void Main(string[] args)         {             SetUserTile(args[0], 0, args[1]);         }     } }


test.cmd
"C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe" "c:\Tile_replace.cs" Tile_replace.exe "%USERNAME%" "C:\ProgramData\Microsoft\User Account Pictures\Default Pictures\usertile12.bmp"








#2 JScript

JScript

    I'm back ... I miss, why not!

  • Active Members
  • PipPipPipPipPipPip
  • 1,070 posts

Posted 17 April 2011 - 08:59 PM

I have not tested, but I think it should look like:
$sUserName = "UserName" $sPicPath = "C:\pic.jpg" $hPicPath = DLLStructCreate("wchar[128]") DllStructSetData($hPicPath, 1, $sPicPath) $hUserName = DLLStructCreate("wchar[128]") DllStructSetData($sUserName, 1, $sUserName) $aRet = DllCall(@SystemDir & "\shell32.dll", "long", 262, "ptr", DllStructGetPtr($hUserName), "int", 0, "ptr", DllStructGetPtr($hPicPath)) MsgBox(4096, "SetUserTile", $aRet[1])

http://notebook.forumais.com (Forum Maintenance Notebooks and Desktop)http://autoitbrasil.com/ (AutoIt v3 Brazil!!!)
Spoiler

Posted Image Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere!       


#3 rvdmast

rvdmast

    Seeker

  • Active Members
  • 7 posts

Posted 31 May 2011 - 07:46 AM

NDog, did you get this working?

I recently discovered Joco's article too and built the .exe.
but i too would like to convert it to AutoIt as we use that
for our login scripts.
But i cannot get jscript's example to work.
$aRet[1]
does return something but nothing
happens, no usertile is created...

#4 rvdmast

rvdmast

    Seeker

  • Active Members
  • 7 posts

Posted 31 May 2011 - 09:04 AM

Ok for anyone else looking into creating UserTile's with AutoIt,
I think i found it:
In this thread the original
author fejesjoco suggested you might have to call CoInitialize first.
Also, the username needs to be in DOMAIN\username or COMPUTERNAME\username format
So now it looks like this:

$sUserName = "DOMAIN\rvdmast" $sPicPath = "\\server\data\fotos\rvdmast.jpg" ; call CoInitialize DLLCall("ole32.dll","int","CoInitialize","ptr",0) $hPicPath = DLLStructCreate("wchar[128]") DllStructSetData($hPicPath, 1, $sPicPath) $hUserName = DLLStructCreate("wchar[128]") DllStructSetData($hUserName, 1, $sUserName) $aRet = DllCall(@SystemDir & "\shell32.dll", "long", 262, "ptr", DllStructGetPtr($hUserName), "int", 0, "ptr", DllStructGetPtr($hPicPath)) MsgBox(4096, "SetUserTile", $aRet[0])


This seems to work.

#5 UglyBob

UglyBob

    Seeker

  • Active Members
  • 26 posts

Posted 14 October 2011 - 07:25 AM

Thanks for this, I've also been looking at this recently because I looking at making use of photos stored in AD and wanted to combine the c# and powerscript into one logon script.

For those interested:

AutoIt         
$objConnection = ObjCreate ( "ADODB.Connection" ) $objConnection.Provider = "ADsDSOObject" $objConnection.Open ( "Active Directory Provider" ) ; Set AD connection for command $objCommand = ObjCreate ( "ADODB.Command" ) If Not IsObj ( $objCommand ) Then     Exit EndIf $objCommand.ActiveConnection = $objConnection $objRootDSE = ObjGet ( "LDAP://RootDSE" ) If @Error Then     Exit EndIf $strDNSDomain = $objRootDSE.Get ( "defaultNamingContext" )  ; Retrieve the current AD domain name $strHostServer = $objRootDSE.Get ( "dnsHostName" ) $strQuery = "<LDAP://" & $strHostServer & "/" & $strDNSDomain & ">;(sAMAccountName=" & @UserName & ");distinguishedName;subtree" $objRecordSet = $objConnection.Execute ($strQuery) $LDAP = ObjGet ( "LDAP://" & $objRecordSet.fields (0).value ) $thumbnailPhoto = $LDAP.thumbnailPhoto $objConnection.Close ( ) If $thumbnailPhoto = "" Then     Exit EndIf     ; Store the User's photo in their profile folder $File = FileOpen ( @UserProfileDir & "\usertile.jpg", 18 ) FileWrite ( $File, $thumbnailPhoto ) FileClose ( $File )   ; call CoInitialize DLLCall("ole32.dll","int","CoInitialize","ptr",0) $hPicPath = DLLStructCreate("wchar[128]") DllStructSetData($hPicPath, 1, @UserProfileDir & "\usertile.jpg") $hUserName = DLLStructCreate("wchar[128]") DllStructSetData($hUserName, 1,  @LogonDomain & "\" & @UserName) $aRet = DllCall(@SystemDir & "\shell32.dll", "long", 262, "ptr", DllStructGetPtr($hUserName), "int", 0, "ptr", DllStructGetPtr($hPicPath))  


If no image is stored then you could always use a default image such as company logo etc.
"My God, you're looking hideously ugly today, Ugly Bob."

#6 Chris866

Chris866

    Seeker

  • New Members
  • 2 posts

Posted 30 November 2011 - 01:18 PM

Hello,

I've been looking for a way to change users tile image for a long time but for some reason the answers in this post don't seem to work for me and I don't understand why. I copied rvdmast's post, added some consolewrite debugging lines:


Plain Text         
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=chg_profile_pic.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** If @UserName = "administrator" Then     $domain = "\\" & EnvGet("JOINEDDOMAIN") Else     $domain = EnvGet("LOGONSERVER") EndIf $sUserName = "mathsdom\ad453" $sPicPath = $domain & "\websites\htdocs-damtp\people\photos\all\root-pr.jpg" ; call CoInitialize $dllcl = DLLCall("ole32.dll","int","CoInitialize","ptr",0) ConsoleWrite ("$dllcl = " & $dllcl[1] & @CRLF) $hPicPath = DLLStructCreate("wchar[128]") ConsoleWrite ("$hPicPath = " & $hPicPath & @CRLF) $hUserName = DLLStructCreate("wchar[128]") DllStructSetData($hUserName, 1, $sUserName) ConsoleWrite ("$hUserName = " & $hUserName & @CRLF) $aRet = DllCall(@SystemDir & "\shell32.dll", "long", 262, "ptr", DllStructGetPtr($hUserName), "int", 0, "ptr", DllStructGetPtr($hPicPath)) MsgBox(4096, "SetUserTile", $aRet[0])


and get the following back:

+>13:08:34 AU3Check ended.rc:0 >Running:(3.3.6.1):C:\Program Files\AutoIt3\autoit3.exe "\\mathsdom\netlogon\scripts\change_profile_picture\change_picture2.au3"    $dllcl = 0x00000000 $hPicPath = $hUserName = +>13:08:36 AutoIT3.exe ended.rc:0 >Exit code: 0   Time: 3.026


the msgbox returns with:

---------------------------
SetUserTile
---------------------------
-2147024893
---------------------------
OK
---------------------------

The tile doesn't change.

I don't understand all this Dll calling so I don't knwo what I should be getting back.

Anyone have any ideas what's going on?

cheers

Chris

#7 Chris866

Chris866

    Seeker

  • New Members
  • 2 posts

Posted 01 December 2011 - 09:23 AM

OK, problem solved, script now working. The cause was a mixture of my lack of understanding of the DLLCall, DLLStructCreate etc commands and also me passng the wrong domanusername. For those reading this thread wanting to script the user profile 'tile' change, this is what I've learnt.

First, the Autoit script that works:

$sUserName = @LogonDomain & "" & @UserName $sPicPath = EnvGet("LOGONSERVER") & "websiteshtdocs-damtppeoplephotosall" & @UserName & "-pr.jpg" ; call CoInitialize $dllcl = DLLCall("ole32.dll","int","CoInitialize","ptr",0) ;~ ConsoleWrite ("$dllcl = " & $dllcl[1] & ", @error = " & @error &  @CRLF) $hPicPath = DLLStructCreate("wchar[128]") DllStructSetData($hPicPath, 1, $sPicPath) ;~ ConsoleWrite ("$hPicPath = " & DllStructGetData  ($hPicPath, 1) & @CRLF) $hUserName = DLLStructCreate("wchar[128]") DllStructSetData($hUserName, 1, $sUserName) ;~ ConsoleWrite ("$hUserName = " & DllStructGetData  ($hUserName, 1) & @CRLF) ;~ ConsoleWrite ("DllStructGetPtr($hUserName) = " & DllStructGetPtr($hUserName) & @CRLF) ;~ ConsoleWrite ("DllStructGetPtr($hPicPath) = " & DllStructGetPtr($hPicPath) & @CRLF) $aRet = DllCall(@SystemDir & "shell32.dll", "long", 262, "ptr", DllStructGetPtr($hUserName), "int", 0, "ptr", DllStructGetPtr($hPicPath)) ;~ ConsoleWrite ("$aRet = " & @error & @CRLF) ;~ MsgBox(4096, "SetUserTile", $aRet[0])



I use a samba server for our Win7 Pro clients. In the script above I was using the wrong domain name, I was using the samba servers netbios name. This isused so many times when authenticating to net shares etc, I just got the wrong on. Then is was my lack of understanding about DLL's. First you 'call' one, then you create its structure, then you probe it - DllStructGetPtr. All being well, when the script is run, you should get a '0' as a result. What this is done is to make a new/modified .dat file in C:Usersall usersMicrosoftUser Account Pictures. The name of tis dat file will be in the form [domain name]+[username].dat. This is all that needed to change the profile tile, the change is immediate.

I also created an exe as per http://www.networksteve.com/forum/topic....tart_Menu_&_Logon/?TopicId=175. In notepad, cut-n-paste:

using System; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Program { [DllImport("shell32.dll", EntryPoint = "#262", CharSet = CharSet.Unicode, PreserveSig = false)] public static extern void SetUserTile(string username, int whatever, string picpath); [STAThread] static void Main(string[] args) { SetUserTile(args[0], 0, args[1]); } } }


Save this file as something.cs, e.g. profiletile.cs. Then compile it with:

c:WINDOWSMicrosoft.NETFrameworkv2.0.50727csc.exe profiletile.cs


This should produce a file called profiletile.exe. The syntax of the file is:

profiletile.exe domainusername full_path_to_jpg


Again, all this program does to create/modify the domain+username.dat file

Hope this helps others looking for a way to script a user profile tile change, good luck :D

#8 NDog

NDog

    Adventurer

  • Active Members
  • PipPip
  • 107 posts

Posted 29 February 2012 - 09:12 AM

Thanks everyone for your contributions and working solutions. I have re read this thread as before I was sticking to the .net compiled version as it is only 4KB and works. However I am now having to compile an all in one embedded new user type script so this comes in useful.. Now if only anyone knows how to change the windows XP user tile easily please share...

#9 NDog

NDog

    Adventurer

  • Active Members
  • PipPip
  • 107 posts

Posted 05 April 2012 - 01:32 PM

To change windows xp tiles this is easy, suprised no one beat me to it

HKLMSoftwareMicrosoftWindowsCurrentVersionHints%USERNAME% - PictureSource - REG_SZ - C:Documents and SettingsAll UsersApplication DataMicrosoftUser Account PicturesDefault Picturespicture.bmp

also windows copies that picture.bmp to C:Documents and SettingsAll UsersApplication DataMicrosoftUser Account Pictures and names it as %USERNAME%.bmp

#10 Khalid

Khalid

    Seeker

  • Normal Members
  • 2 posts

Posted 09 October 2012 - 11:46 AM

Thanks for this, I've also been looking at this recently because I looking at making use of photos stored in AD and wanted to combine the c# and powerscript into one logon script.

<snip>

$LDAP = ObjGet ( "LDAP://" & $objRecordSet.fields (0).value )

<snip>

[/autoit]

Thanks for the code; it works great -- for a valid user, that is. If I supply a non-existent user to the code, I get the following error:

==> The requested action with this object has failed.

Which is OK and expected. However, the script stops executing! I would like the script to continue with the rest of the code. I have even tried using "if (isObj $LDAP) then ..." to catch the error, but the script just bombs out.

How can I ignore this error and carry on with the rest of the code?

Any help would be much appreciated!




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users