Jump to content

Recommended Posts

Posted (edited)

Hello,

 

Let's say I have 2 printers under Windows 7 x64. I have 2 scripts to set each of the 2 printers as default and I pinned shortcuts to those 2 scripts to the taskbar. They work fast.

I've been meaning to add some dynamic icons for these shortcuts so that when I set a printer as default, its shortcut gets a colored icon and the other printer's shortcut gets b/w icon. Not many viable options to do this, but I found some code here on the forum and I adapted it to my situation. I made a .dll file with the 4 icons I need to use, because it seems that the code won't work with .ico.

 

I will post the code below, but first let me tell you which my problems are:

- the icon change in the folder where I have all files (the 2 .vbs, the 2 .lnk, icons.dll) happens in 15-20 seconds, which is a bit slow given the fact that the default printer change takes place in 1 second - this happens even if I refresh the folder (F5) repeatedly

- the icon change doesn't happen at all for the icons in taskbar (I made shortcuts correctly, with target: C:\Windows\System32\wscript.exe "E:\Printers\Bro.lnk")

 

It might be the code I use that is wrong and maybe you guys can help me make it better. Here it is:

 

Set WshNetwork = WScript.CreateObject("WScript.Network")
PrinterPath = "Brother DCP-T300"
WshNetwork.SetDefaultPrinter PrinterPath

Set objShell = CreateObject("Shell.Application")
   Set objFolder = objShell.NameSpace("E:\Printers")

   Set objFolderItem = objFolder.ParseName("Bro.lnk")
   Set objShortcut = objFolderItem.GetLink
objShortcut.SetIconLocation "E:\Printers\icons.dll" ,0
objShortcut.Save

   Set objFolderItem = objFolder.ParseName("Bul.lnk")
   Set objShortcut = objFolderItem.GetLink
objShortcut.SetIconLocation "E:\Printers\icons.dll" ,3
objShortcut.Save
   
WScript.Quit 1

 

Please help me make this faster, or if not possible please at least tell me why.

About the taskbar thing, I can live without it since it works for desktop shortcuts.

 

Please don't say I'm too picky and that it takes 3 seconds to switch between printers via CPanel - I know.

I might as well be using 5 printers on a tight schedule and need to switch between them pretty fast without having always to right click and set as default printer.

 

Thank you in advance.

Edited by Mrrrr
change title
Posted
the icon change in the folder where I have all files (the 2 .vbs, the 2 .lnk, icons.dll) happens in 15-20 seconds, which is a bit slow given the fact that the default printer change takes place in 1 second - this happens even if I refresh the folder (F5) repeatedly

Does running DesktopRefresh.exe make the icon change happen any faster?

Posted (edited)
Does running DesktopRefresh.exe make the icon change happen any faster?

Yes, a bit faster, like 10 seconds when it did 20 otherwise. Still a bit slow, but acceptable I guess.

Couldn't I trigger an F5 on desktop via one / a few line of code instead? If I would prefer not to use an additional exe. And without killing explorer.exe.

 

I thought you could set default printers based upon network location/domain, can you not do this?

I could, but these 2 printers are local. For my needs, I have a normal printer, a virtual pdf printer and a printer for a certain type of paper (C5 envelopes). All local. Why would I require to set defaults based on network location/domain? Or maybe I don't understand what you mean, then sorry :)

Edited by Mrrrr
added more req
Posted
Couldn't I trigger an F5 on desktop via one / a few line of code instead?

Yes. That easy to do with a PowerShell script. Copy-and-paste all of the code below into Notepad and then save as RefreshDesktop.ps1 (or whatever you want to call it).

 

function Update-ExplorerIcon {
 [CmdletBinding()]
 param()

 $code = @'
private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff); 
private const int WM_SETTINGCHANGE = 0x1a; 
private const int SMTO_ABORTIFHUNG = 0x0002; 


[system.Runtime.InteropServices.DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern bool SendNotifyMessage(IntPtr hWnd, uint Msg, UIntPtr wParam,
  IntPtr lParam);

[system.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
 private static extern IntPtr SendMessageTimeout ( IntPtr hWnd, int Msg, IntPtr wParam, string lParam, uint fuFlags, uint uTimeout, IntPtr lpdwResult ); 


[system.Runtime.InteropServices.DllImport("Shell32.dll")] 
private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);


public static void Refresh()  {
   SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);
   SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, null, SMTO_ABORTIFHUNG, 100, IntPtr.Zero); 
}
'@

 Add-Type -MemberDefinition $code -Namespace MyWinAPI -Name Explorer 
 [MyWinAPI.Explorer]::Refresh()

}

Update-ExplorerIcon

 

I am not sure how you would do the same thing in VBScript. I stopped using it over 9 years ago.

 

Btw, I don't think the rundll32 method works anymore on Windows 7 onwards.

 

Dim oShell
Set oShell = CreateObject("WScript.Shell")

oShell.Run "%WinDir%\System32\RUNDLL32.EXE user32.dll,"_
 & "UpdatePerUserSystemParameters",1 ,true

Set oShell = Nothing
wscript.quit

 

Yes, a bit faster, like 10 seconds when it did 20 otherwise. Still a bit slow, but acceptable I guess.

The PowerShell script above refreshes the desktop instantly (at least it did when I tested it on my PC).

  • Thanks 1
Posted
Yes. That easy to do with a PowerShell script. Copy-and-paste all of the code below into Notepad and then save as RefreshDesktop.ps1 (or whatever you want to call it).

 

I should get used to PowerShell scripts. Never needed one before. I will have to dig deeper and see the many benefits of PS.

 

I am not sure how you would do the same thing in VBScript. I stopped using it over 9 years ago.

 

Btw, I don't think the rundll32 method works anymore on Windows 7 onwards.

 

Dim oShell
Set oShell = CreateObject("WScript.Shell")

oShell.Run "%WinDir%\System32\RUNDLL32.EXE user32.dll,"_
 & "UpdatePerUserSystemParameters",1 ,true

Set oShell = Nothing
wscript.quit

 

Seems that it's instant on Win7 SP1 x64 and it's exactly what I need, thank you very much. I wanna use VBS because at work there are a few PCs still using XP.

 

As for my need to add them to taskbar, well, I figured a workaround. I put the shortcuts in a folder (just them alone), then made a new toolbar on the Taskbar with that folder. Now the icons change also in Taskbar, instantly thanks to your code.

 

Much appreciated!

  • 2 weeks later...
Posted

Hello again,

 

Regarding this matter, I've ran into a bit of a problem.

Running rundll32 seems to be creating more rundll32.exe processes and it sometimes hangs the icon changing of my shortcuts. I sometimes have to press twice on a shortcut to see its icon changed, even though the printer changes.

I noticed there are multiple instances of rundll32.exe and upon closing them, the vbs started working well again.

 

So...

 

Is it possible to close all instances of rundll32.exe on current user account (or a specified user account) at the end of the code, before exiting wscript?

For example, now they are 3, plus 1 on the administrator account on this PC which can't be killed and I wouldn't want to anyway.

The purpose would be, I guess, just to reset them in case any of those instances hang. Maybe there is an option to "refresh" the instances, and not kill them.

Posted
Hello again,

 

Regarding this matter, I've ran into a bit of a problem.

Running rundll32 seems to be creating more rundll32.exe processes and it sometimes hangs the icon changing of my shortcuts. I sometimes have to press twice on a shortcut to see its icon changed, even though the printer changes.

I noticed there are multiple instances of rundll32.exe and upon closing them, the vbs started working well again.

 

So...

 

Is it possible to close all instances of rundll32.exe on current user account (or a specified user account) at the end of the code, before exiting wscript?

For example, now they are 3, plus 1 on the administrator account on this PC which can't be killed and I wouldn't want to anyway.

The purpose would be, I guess, just to reset them in case any of those instances hang. Maybe there is an option to "refresh" the instances, and not kill them.

 

 

This VBS key will refresh the desktop for you without running rundll32.exe.

 

DesktopRefresh.vbs

 

Hope this helps.

Posted

Thanks, but I had found a similar F5-refresh code before asking a question here, tried it and it wasn't changing icons in 1 second (like rundll32 does), but in 15-20 seconds. Even if I manually pressed F5 a couple of times, it still took 15-20 seconds for the icons of the shortcut files to change.

 

Plus, I don't have the icons on desktop, but in a toolbar created on the taskbar.

I tried to use the refresh vbs code for that folder too, but it will make the change in 15-20 seconds (rundll32 does it almost instantly).

 

I don't want to use the powershell code, which probably has nothing to do with starting rundll32.exe (or at least I can't see it in the code from post #5), because some PCs here still have Windows XP or Vista (afaik Powershell is not installed by default in Vista).

So I wanted to implement a method that would work on all PCs.

Posted (edited)
I don't want to use the powershell code, which probably has nothing to do with starting rundll32.exe (or at least I can't see it in the code from post #5), because some PCs here still have Windows XP or Vista (afaik Powershell is not installed by default in Vista).

Since the majority of the code in the PowerShell script isn't actually PowerShell you should be able to create an EXE from it that doesn't require PowerShell to run.

 

@localzuk or @Steve21 might be able to help? :)

Edited by Arthur
Posted

I tried compiling/packaging that myself with f2ko online and with software, and Kaspersky sees it as virus. I'm assuming it's because it's code.

 

How would I call it via vbs so it refreshes the icon cache?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...