Link to home
Start Free TrialLog in
Avatar of RKoons
RKoonsFlag for United States of America

asked on

Virtual Basic Question...

I found the following vbs script that will install fonts into the fonts folder of a Windows 7 workstation:

Const FONTS = &H14&

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(FONTS)
objFolder.CopyHere "location\font.ttf"


The only thing you have to do is replace "location", with where the fonts are stored, and the font name, for "font".

I am planning on using this with Group Policy to automate font installation.

The problem is: after it has run once, when the user logs in again, it will ask them if they want to replace to font that is already installed.

I am NOT a vbs expert (unfortunately) so what I need is:

How can I add some code so that it checks if the font already exists before it installs it?

Thanks
Avatar of Qlemo
Qlemo
Flag of Germany image

CopyHere supports a second parameter for options, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms723207(v=vs.85).aspx .  In this case I would use 1024 to not show any error dialog:
objFolder.CopyHere "location\font.ttf", 1024

Open in new window

Const FONTS = &H14&

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(FONTS)
Set objFolderItem = objFolder.Self
Wscript.Echo objFolderItem.Path

Open in new window

Avatar of RKoons

ASKER

I thank you both for your response, however:

Qlemo: This does not work with the script I am using. Looking at the article, I'm not sure the syntax is the same (System.Shell.Folder.copyHere & objFolder.CopyHere)

Jeff: All this does is display the path to the fonts folder... (In all fairness, it does that VERY well...).
Is there a reason you're not sharing the article?
Avatar of RKoons

ASKER

...The article noted by Qlemo...:

Link from above.
Your objFolder is of type System.Shell.Folder ...
What exactly does not work with my suggestion?
Avatar of RKoons

ASKER

The popup is not strictly an error as it is an option dialog; giving the user the option to re-install the font.

I'm not sure if this is why, but the dialog still pop's up.

I believe that it is working, because I do not get any error messages when it runs.

This is the extent of the code (with the 1024 removed):

Const FONTS = &H14&

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(FONTS)
objFolder.CopyHere "\\server name\Distribution\IDOTFONTS\FDOT.ttf"


When added, I made it look just like your example. I also tried adding 16, as that seemed to also make scene.

FYI: Each user has local admin rights on the workstations.
Silly question, I'm sure...

Why not just check if the file exists before you attempt to copy it?

https://blogs.technet.microsoft.com/heyscriptingguy/2005/06/20/how-can-i-determine-if-a-file-exists-and-if-it-does-exit-the-script/
Avatar of RKoons

ASKER

Not silly...

I have over 150 machines that needs this done to it. So, I am planning on pushing this via GPO.

I know it will work, but I have to leave the GPO active at least until I can be sure that every machine has gotten the update. In the mean time, every machine that has already been loaded, will get that "are you sure you want to re-install..." message every time they reboot.

So I need a way for the script to know if it has already done the job or not, so that the install process can be skipped if it has been.
So I need a way for the script to know if it has already done the job or not, so that the install process can be skipped if it has been.
So, I'll repeat:
Why not just check if the file exists before you attempt to copy it?
If it exists, it's been run before and can be skipped.  If not, it copies it.  Where's the problem?
Avatar of RKoons

ASKER

Group policy will automatically run the GPO object every time the machine is started. So, if I am correct, the script will try and load the fonts again each time the user reboots.

The only other option I am aware of, is to do it manually for over 150 machines... which I would like to avoid.
Ah of course, %WinDir%\fonts is a special folder type with added features. it is not the copy operation itself, but what is triggered instead in the background (the font installation dialog).
In that case it is indeed best to first check for the file locally.
Const FONTS = &H14& 

set objFolder = CreateObject("Shell.Application").Namespace(FONTS)
if (!CreateObject("Scripting.FileSystemObject").FileExists(objFolder.Self.Path)) then
  objFolder.CopyHere "\\server name\Distribution\IDOTFONTS\FDOT.ttf" 
end if

Open in new window

Avatar of RKoons

ASKER

Thanks...

I have to switch gears for a bit, but I will try this before the end of the day...

BTW... I have been trying to learn VB, but have yet to find a way that is "NOOB' friendly.

Any suggestions?
I don't know how to make this any clearer - make your script CHECK if the font is there.  If it is, then you SKIP installing it.  The Group Policy can apply for all time (are NEVER getting new machines?).
Avatar of RKoons

ASKER

LEE W, MVP said:

I don't know how to make this any clearer - make your script CHECK if the font is there.  If it is, then you SKIP installing it.  The Group Policy can apply for all time (are NEVER getting new machines?).

...Let me make this clearer...

The reason I am here, asking these questions, is because I know I need to do that, but, until Qlemo and others made a helpful suggestion, I have no idea how.

So, what I am looking for, is helpful suggestions, not the pointing out of the obvious...
Avatar of RKoons

ASKER

Qlemo:

I tried your suggestion noted above and it does not like the !.

I get a Syntax error:

Line 4
Char 5

Code: 800A03EA

I replace ! with NOT, which works, but the second "Run and skip" does not...
I provided the link with instructions how to do if DAYS ago. You didn't even acknowledge that.  If you don't have the skill to incorporate the information I provided, say so! I didn't just say "check if if exists" I provided a link to a Microsoft blog that details how check a file exists in vb.

I don't have time to code if now as I'm on an android tablet. But if you had said "good idea... But I don't know how to incorporate that code" in the first place, I'm sure I or one if the other posters would have had this solved four you DAYS ago. HELP US HELP YOU
Avatar of RKoons

ASKER

Lee w.

My mistake.

All i saw was your tone, and i missed your link.
And it seems you likely misread my tone because you didn't read my earlier posts.  Now you see why I'm frustrated trying to help you.
Sorry, I forgot the font name in the existence check ...
Const FONTS = &H14&
FontName = "FDOT.ttf"

Set objFolder = CreateObject("Shell.Application").Namespace(FONTS)
If (Not CreateObject("Scripting.FileSystemObject").FileExists(objFolder.Self.Path + "\" + FontName)) Then
  objFolder.CopyHere "\\server name\Distribution\IDOTFONTS\" + FontName
End If

Open in new window

Avatar of RKoons

ASKER

Didn't want you to think I forgot.

I will try again later today or tomorrow at the latest.

Will be out the rest of the day!
Avatar of RKoons

ASKER

Qlemo:

I must be starting to get the hang of this because I was able to change the script to make it copy right, but cannot get it to NOT copy once it is there.

Otherwise, after adding the server name, it does not error out, and when I run it under CSCRIPT //X there are also no errors. It just runs, and does nothing.

...Sorry, and thanks for the effort so far.
Then you might want to use some debugging output.
Const FONTS = &H14&
FontName = "FDOT.ttf"

Set objFolder = CreateObject("Shell.Application").Namespace(FONTS)
If (Not CreateObject("Scripting.FileSystemObject").FileExists(objFolder.Self.Path + "\" + FontName)) Then
  objFolder.CopyHere "\\server name\Distribution\IDOTFONTS\" + FontName
else
  WScript.Echo 'Font already there'
End If

Open in new window

Avatar of RKoons

ASKER

Thanks, and sorry for the delay!

I will test this tomorrow at the latest.
Avatar of RKoons

ASKER

Sorry for the delay on this one, but I got pulled away and this is the first change I have had.

What I found out, and I think why this has not worked, is because it seems that the restriction for automating copying things into the fonts folder has something to do with copying them from the network directly into the fonts folder.

It seems that the solution is to copy them first into a local folder, and then from there into the fonts folder.

Can you add that part to the script and we'll see if that works?


Thanks!
Const FONTS = &H14
Const LOCALAPPDATA = &H1c
FontName = "FDOT.ttf"

Set objFontsFolder = CreateObject("Shell.Application").Namespace(FONTS)
Set objTmpFolder = CreateObject("Shell.Application").Namespace(LOCALAPPDATA)
If (Not CreateObject("Scripting.FileSystemObject").FileExists(objFolder.Self.Path + "\" + FontName)) Then
  objTmpFolder.CopyHere "\\server name\Distribution\IDOTFONTS\" + FontName
  objFontFolder.MoveHere objTmpFolder.ParseName(FontName).Path
else
  WScript.Echo 'Font already there'
End If

Open in new window

but I don't think that changes anything.
Avatar of RKoons

ASKER

User generated image
Any Thoughts?

This is what happens when I run it.
ASKER CERTIFIED SOLUTION
Avatar of Qlemo
Qlemo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Meets the requirements of the question.  I agree that this should be the solution.