Что нового

[Автоматизация] Как быстро установить множество шрифтов?

warezoogle3

Новичок
Сообщения
73
Репутация
1
Добрый день!
Понадобилось установить около 300 шрифтов на рабочие машины.
Раньше разок тоже понадобилось и Уважаемый Garrett предоставил мне вот это
Код:
Const $FONTS   = 0x14

$oShell   = ObjCreate("Shell.Application")
$oWinFonts   = $oShell.Namespace($FONTS)

; шрифты должны быть в директории скрипта
$sFirstFile = FileFindFirstFile("*.*")

If $sFirstFile = -1 Then
    Exit
EndIf

While 1
    Local $sFile = FileFindNextFile($sFirstFile)
    If @error Then ExitLoop
    Switch StringRight($sFile, 3)
    Case 'ttf', 'otf', 'pfm', 'fon'
        $sWinFontsPath = @WindowsDir & '\Fonts\' & $sFile
        $sLocFontsPath = @ScriptDir & '\' & $sFile
        If NOT FileExists($sWinFontsPath) Then
            $oWinFonts.CopyHere($sLocFontsPath)
        Else
            MsgBox(262144, $sFile, 'Файл уже установлен', 1)
        EndIf
    EndSwitch
WEnd
,за что огромное спасибо ему,но...
этот код отлично работает,есть требуемых установить шрифтов очень немного,а при 300 штук работает очень медленно,даже быстрее делать в ручную. А этот скрипт единственный (который у меня есть),который не требует перезагрузки операционной системы,а это для меня очень важно.
Кстати,я немного изменил скрипт и получилось вот так
Код:
Const $FONTS = 0x14

$oShell = ObjCreate("Shell.Application")
$oWinFonts = $oShell.Namespace($FONTS)

; Fonts must be in the same directory
$sFirstFile = FileFindFirstFile("*.*")

If $sFirstFile = -1 Then
	Exit
EndIf

While 1
	Local $sFile = FileFindNextFile($sFirstFile)
	If @error Then ExitLoop
	Switch StringRight($sFile, 3)
		Case 'ttf', 'otf', 'pfm', 'fon'
			$sWinFontsPath = @WindowsDir & '\Fonts\' & $sFile
			$sLocFontsPath = @ScriptDir & '\' & $sFile
			If Not FileExists($sWinFontsPath) Then
				$oWinFonts.CopyHere($sLocFontsPath)
				$FontTitle = "Install Font"
				If WinExists("$FontTitle") Then
					WinActivate($FontTitle)
					WinWaitActive($FontTitle)
					ControlClick($FontTitle, "", "Button1")
				EndIf
			Else
				MsgBox(262144, $sFile, 'The font is already installed', 1)
			EndIf
	EndSwitch
WEnd

Но дело в том,моя добавленная часть,то есть
Код:
$FontTitle = "Install Font"
				If WinExists("$FontTitle") Then
					WinActivate($FontTitle)
					WinWaitActive($FontTitle)
					ControlClick($FontTitle, "", "Button1")

не работает (это часть кода должна проверять,есть ли окно,говорящее,что шрифт уже установлен, нажать кнопку да,чтобы заменить/замещать его).

То есть у меня сразу две проблемы/задачи:
1.Медленно работающий код
2.Вообще не работающая часть кода

Помогите пожалуйста,очень прошу!
Заранее огромное спасибо!
:beer: :IL_AutoIt_1:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
warezoogle3 [?]
2.Вообще не работающая часть кода
Замените на
Код:
;...
If WinExists($FontTitle) Then
;...

+
Предупреждение За нарушение общих правил (пункт В.4):
Не лепите несколько вопросов разной тематики в один пост. По типу "Ребят, а ещё такой вопрос...". Каждый вопрос в свою тему.


С уважением, ваш Модератор.
 
Автор
W

warezoogle3

Новичок
Сообщения
73
Репутация
1
Поменял код,как Вы сказали(лишние знаки были),но опять не работает...
Про медленную работу напишу в другую тему,мне бы только ошибку исправить :smile: :beer:


Добавлено:
Сообщение автоматически объединено:

Пожалуйста,помогите! :smile: :beer:
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
warezoogle3 [?]
но опять не работает
Скорее всего код работает, но очень быстро: когда вы проверяете существование окна - его (окна) ещё нет. Попробуйте подождать хотя бы секунду
Код:
If WinWait($FontTitle, "", 1) <> 0 Then
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
warezoogle3 [?]
Поменял код,как Вы сказали(лишние знаки были),но опять не работает...
Попробуйте заменить его на
Код:
;...
$hWin = WinWait('Install Font', '', 3); change 1 or 2 sec.
If $hWin Then
	ControlClick($hWin, '', 'Button1')
EndIf
;...
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Код:
FileCopy(@ScriptDir & '\Fonts\*.ttf', @WindowsDir & '\Fonts')


Это разве не работает? Windows должна сама зарегистрировать все шрифты, которые копируются в папку Fonts.
 
Автор
W

warezoogle3

Новичок
Сообщения
73
Репутация
1
Уважаемый Yashied,так ничего не происходит. :smile:


Добавлено:
Сообщение автоматически объединено:

Уважаемые InnI и madmasles,так тоже не работает. :smile:
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
warezoogle3 [?]
так тоже не работает
А чего вы хотите добиться?
Я на английской Windows XP вручную скопировал файл шрифта в папку Fonts. Появилось окно "Install Font Progress", у которого Button1 - это кнопка "Canсel". Причём окно закрылось автоматически.
Так вы хотите или не хотите устанавливать шрифты?
 
Автор
W

warezoogle3

Новичок
Сообщения
73
Репутация
1
Так вы хотите или не хотите устанавливать шрифты?
Хочу конечно! :smile: И хочу автоматически,но с такой же быстротой и легкостью! :beer:
http://www.youtube.com/watch?v=gujSgIZjBKw


Добавлено:
Сообщение автоматически объединено:

Вот можно ли сделать приблизительно так,как в ссылке с видео,но автоматически? :smile:


Добавлено:
Сообщение автоматически объединено:

Кто-то поможет мне? :beer: :IL_AutoIt_1:
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
warezoogle3 [?]
приблизительно так,как в ссылке
Для русской Windows 7. В папке должны быть ТОЛЬКО файлы шрифтов.
Код:
#include <GuiMenu.au3>
#include <SendMessage.au3>

$Folder = "D:\Шрифты"
Run("explorer.exe " & $Folder)
WinWaitActive("[class:CabinetWClass]")
Send("^a")
Send("{APPSKEY}")
WinWait("[class:#32768]")
$PopUp = _SendMessage(WinGetHandle("[class:#32768]"), 0x01E1, 0, 0) ;MN_GETHMENU
$MenuItem = _GUICtrlMenu_FindItem($PopUp, "Установить", True)
Do
  If _GUICtrlMenu_GetItemHighlighted($PopUp, $MenuItem) Then ExitLoop
  Send("{DOWN}")
Until 0
Send("{ENTER}")
$wnd = WinWait("Установка шрифтов")
Do
  If WinExists("Установка шрифта") Then
    WinActivate("Установка шрифта")
    Send("{TAB}{SPACE}")
    ControlClick("Установка шрифта", "", "Button1") ; заменить
   ;ControlClick("Установка шрифта", "", "Button2") ; не заменять
    WinWaitClose("Установка шрифта")
  EndIf
Until Not WinExists($wnd)
Send("!{F4}")
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Что делает Windows, когда вы добавляете шрифт?

  • Копирует файл шрифта в соответствующую папку.
  • Добавляет шрифт в таблицу шрифтов.
  • Прописывает шрифт в реестре для последующей его загрузки.
  • Посылает широковещательное сообщение WM_FONTCHANGE, говорящее об изменениях в таблице шрифтов.

Вот собственно и все. Если у вас по каким-либо причинам шрифт автоматически не регистрируется в системе после его копирования в папку Fonts, то вы можете проделать вышеперечисленные действия самостоятельно. Никаких окон отлавливать не нужно. Вот код для шрифтов TrueType (для Type1 будет другая ветка реестра и форма записи).

Код:
#RequireAdmin

#Include <APIConstants.au3>
#Include <WinAPIEx.au3>

Global Const $sSrc = @ScriptDir & '\Fonts'
Global Const $sDst = _WinAPI_ShellGetSpecialFolderPath($CSIDL_FONTS)

$hSearch = FileFindFirstFile($sSrc & '\*.ttf')
If $hSearch = -1 Then
    Exit
EndIf

$Count = 0

While 1
    $File = FileFindNextFile($hSearch)
    If @Error Then
		ExitLoop
	EndIf
	$Name = _WinAPI_GetFontResourceInfo($sSrc & '\' & $File, 1)
    If @Error Then
		ContinueLoop
	EndIf
	If Not FileCopy($sSrc & '\' & $File, $sDst & '\') Then
		ContinueLoop
	EndIf
	If Not RegWrite('HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', $Name & ' (TrueType)', 'REG_SZ', $sDst & '\' & $File) Then
		ContinueLoop
	EndIf
	If Not _WinAPI_AddFontResourceEx($sDst & '\' & $File) Then
		RegDelete('HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', $Name & ' (TrueType)')
		ContinueLoop
	EndIf
	$Count += 1
WEnd

FileClose($hSearch)

If $Count Then
	_WinAPI_BroadcastSystemMessage($WM_FONTCHANGE, 0, 0, $BSF_IGNORECURRENTTASK)
EndIf


Т.к. запись идет в HKEY_LOCAL_MACHINE, то скрипт должен быть запущен с правами администратора.

P.S

Кстати, файлы шрифта необязательно копировать в папку Fonts, они могут находиться где угодно. Если не прописывать шрифт в реестр, то он будет существовать только до перезагрузки компьютера. Если не посылать WM_FONTCHANGE, то все приложения, которые работают в данный момент и используют шрифты (например Microsoft Office), не обновят свои списки доступных шрифтов, и вы не сможете использовать установленные шрифты до перезапуска приложения.
 
Автор
W

warezoogle3

Новичок
Сообщения
73
Репутация
1
Уважаемый InnI,все отлично работает,ОГРОМНОЕ СПАСИБО,но никак не могу сделать для английской версии. :smile:
В английской версии есть две надписи: "Installing Fonts" и "Install Font". :beer: :IL_AutoIt_1:

Уважаемый Yashied,все отлично работает для TrueType,ОГРОМНОЕ СПАСИБО,а что поменять,чтобы также установились шрифты с разширением .fon ? :smile: :beer: :IL_AutoIt_1:
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Русский/английский
Код:
#include <GuiMenu.au3>
#include <SendMessage.au3>

If @MUILang = "0419" Then
  $ItemText = "Установить"
  $WndInstallText = "Установка шрифтов"
  $WndConfirmText = "Установка шрифта"
Else
  $ItemText = "Install"
  $WndInstallText = "Installing Fonts"
  $WndConfirmText = "Install Font"
EndIf

$Folder = "D:\FontFiles"

Run("explorer.exe " & $Folder)
WinWaitActive("[class:CabinetWClass]")
Send("^a")
Send("{APPSKEY}")
WinWait("[class:#32768]")
$PopUp = _SendMessage(WinGetHandle("[class:#32768]"), 0x01E1, 0, 0) ;MN_GETHMENU
$MenuItem = _GUICtrlMenu_FindItem($PopUp, $ItemText, True)
Do
  If _GUICtrlMenu_GetItemHighlighted($PopUp, $MenuItem) Then ExitLoop
  Send("{DOWN}")
Until 0
Send("{ENTER}")
$wnd = WinWait($WndInstallText)
Do
  If WinExists($WndConfirmText) Then
    WinActivate($WndConfirmText)
    Send("{TAB}{SPACE}")
    ControlClick($WndConfirmText, "", "Button1") ; заменить/replace
   ;ControlClick($WndConfirmText, "", "Button2") ; не заменять/no replace
    WinWaitClose($WndConfirmText)
  EndIf
Until Not WinExists($wnd)
Send("!{F4}")
 
Автор
W

warezoogle3

Новичок
Сообщения
73
Репутация
1
Уважаемый InnI,все отлично работает,ОГРОМНОЕ СПАСИБО! :beer: :IL_AutoIt_1: :ok:
 
Верх