PDA

View Full Version : опять проблема с кодировкой в 1.8, теперь аут&


gospodin.horoshiy
11-12-2009, 14:43
Продолжаю биться с кодировками в 1.8 по всем фронтам (в основом головой, и в основном об стену)
Теперь вот такая проблема вылезла....

В папочке с агентом 1.8 лежит скрипт uAllPrograms.vbs, который выводит значения для следующего параметра, которые прописан в .conf файле
UserParameter=uAllPrograms, cscript.exe /nologo "C:\Program Files\Zabbix Agent\uAllPrograms.vbs"


( в данном случае скрипт выплевывает этот список установленных программ при помощи WScript.Echo string, так вот, как бы я не пытался, у меня всегда этот аутпут получается в кодировке виндовой, т.е cp1251, когда по новой схеме полагается чтобы все было utf-8 ( кроме eventlog[], где все замечательно работает и так)

В итоге, на стороне сервера в /tmp/zabbix_server.log я вижу что допустим 10ая программа в списке отображается абракадаброй(не утф8), а во фронтэнде так вообще на этой программе список обрывается, т.е. показывает список только из первых 10 программ, хотя за 10, что по-русски написана там идет еще 20 с английскими названиями... ну так вот... Как же все таки теперь получать правильно русские буковки с виндусовой машины?

Вот например есть скрипт
Он берет список программ из функции InstalledApplications а затем конвертирует его в utf8 и выплевывает при помощи Wscript.Echo а также пишет в файл uAllPrograms.txt.
Так вот, когда он выплевывает этот текст через Echo, то это все равно cp1251 а вот зато я открываю файл - и там на самом деле utf8!
То есть конвертилка работает, но почему-то только для файлов...




Const adTypeBinary = 1
Const adTypeText = 2
Const bOverwrite = True
Const bAsASCII = False

Dim oFS : Set oFS = CreateObject( "Scripting.FileSystemObject" )

Dim Output
Dim sTFSpec : sTFSpec = oFS.GetAbsolutePathName( "allPrograms_utf8.txt" )

Dim oFrom : Set oFrom = CreateObject( "ADODB.Stream" )
Dim sFrom : sFrom = "windows-1251"
Dim oTo : Set oTo = CreateObject( "ADODB.Stream" )
Dim sTo : sTo = "utf-8"

If oFS.FileExists( sTFSpec ) Then oFS.DeleteFile sTFSpec

oFrom.Type = adTypeText
oFrom.Charset = sFrom
oFrom.Open
oFrom.WriteText InstalledApplications(".")

oFrom.Position=0
oTo.Type = adTypeText
oTo.Charset = sTo
oTo.Open
oTo.WriteText oFrom.ReadText



oTo.Position=0
Output= oTo.ReadText
oTo.SaveToFile sTFSpec
WScript.Echo Output

oFrom.Close
oTo.Close



'##########################FUNCTION GET PROGRAMS LIST#######################
Function InstalledApplications(node)
Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE
Set oRegistry = GetObject("winmgmts://" _
& node & "/root/default:StdRegProv")
sBaseKey = _
"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstal l\"
iRC = oRegistry.EnumKey(HKLM, sBaseKey, arSubKeys)

For Each sKey In arSubKeys

iRC = oRegistry.GetStringValue( _
HKLM, sBaseKey & sKey, "DisplayName", sValue)
If iRC <> 0 Then
oRegistry.GetStringValue _
HKLM, sBaseKey & sKey, "QuietDisplayName", sValue
End If
If sValue <> "" and instr(sValue, "KB")=0 and instr(InstalledApplications, sValue&vbCrLf)=0 Then
InstalledApplications = _
InstalledApplications & sValue & vbCrLf
End If
Next
End Function

Народ, наверняка уже столкнулся кто-то с подобными проблемами, если нужно русский текст с Win32 забрать...как это решить, мне кажется что я сильно запутался с кодировками... :)

gospodin.horoshiy
15-12-2009, 11:20
Люди, выручайте :)

Никак не могу осилить:

мне нужно чтобы параметр с агента 1.8

UserParameter=uAllPrograms, cscript.exe /nologo "C:\Program Files\Zabbix Agent\uAllPrograms.vbs"

работал, у меня когда в выводе скрипта оказываются русские буквы, то все, приходит пустое поле в заббиксе.... уже добился того, чтобы вывод из uAllPrograms.vbs у меня был в utf8, но вот аутпут того, чтоб посылается на сервер все равно получается фигня какая то.... смотрю

лог /tmp/zabbix_server.log - там что приходит из русского явно не утф8......

Я чувствую что я запутался окончательно с кодировками, понимаю только, что на сервак должно прийти utf-8, а вот где какая у винды и тд - непонимаю....

Как мне в 1.8 с винды русские буковки передать через агент или zabbix_sender.exe?
Помогите пожалуйста!

kodmis
16-12-2009, 07:56
А если сам скрипт сохранить в UTF8 (только наверное придется переделать в uAllPrograms.wsh)?
Он не будет выплевывать сразу в UTF8?

gospodin.horoshiy
16-12-2009, 12:12
Нет, если конвертнуть скрипт в УТФ8 и поменять на wsh, то скрипт вообще не запускается....

Проблема думаю кроется в том, что как не крути, вывод в консоли cmd всегда получается в досовской кодировке, например, когда ты редиректишь аутпут в файл: типа csript.exe /nologo 1.vbs > 1.txt

В лучшем случае можно использовать ключ /U, вот так
cscript.exe /nologo /U 1.vbs > 1.txt, тогда он создает в кодировке уникодовской, но не УТФ-8, насколько я понимаю.....

Как бы выкрутиться....

kodmis
16-12-2009, 14:39
WSH в UTF8 должен прекрасно запускаться. Просто обязан .
Вы же не забыли в первой строке xml указать utf8 кодировку?
<?xml version="1.0" encoding="UTF-8"?>

И вот еще посмотрите:
http://forum.script-coding.info/viewtopic.php?id=135

gospodin.horoshiy
17-12-2009, 12:08
Да попробовал через .wsh : вот так:
uAllprograms.wsh

<?xml version="1.0" encoding="UTF-8"?>
[ScriptFile]
Path=uAllPrograms.vbs
[Options]
Timeout=0
DisplayLogo=0

wsh файл в виде утф8, и вроде запускается... но команда:

cscript.exe /nologo "C:\Program Files\Zabbix Agent\uAllPrograms.wsh"Все равно выдает аутпут в виде cp866 который заббикс читать не собирается ...

А если при этом поменять кодировку vbs файла, то в итоге wsh не запустится...

То есть нужно поменять кодовую страницу на 65001 в консоли на время выполнения команды заббикс агентом что ли... не уверен...

Блин, так нужно чтобы эти скрипты заработали!
Люди плиз, думаю для полной мультиязыковости заббикса неплохо бы разобраться!

kodmis
17-12-2009, 12:26
А если запускать zabbix sender сразу из скрипта? Т.е. без вывода в stdout

gospodin.horoshiy
17-12-2009, 12:53
zabbix_sender удалость заставить работь , когда его выполняешь внутри vbs скрипта, предварительно внутри скрипта подправив кодировочки.....


только кроме sender'a нужно чтобы еще и zabbix_agentd тоже мог выполнять через userparameter...

gospodin.horoshiy
17-12-2009, 13:27
Может разработчики прокомментируют? Ну хоть чуть-чуть :)

zalex_ua
27-07-2010, 04:25
Ну и как ничего не изменилось? Или есть решение?
Если нет, тогда для затравки выдаю пару интересных команд:
cmd /?
chcp /?
cscript /?
Правда сколько я не мучался, ничего они мне полезного не дали.:mad:
Вот еще
http://anvarichn.livejournal.com/43752.html

gospodin.horoshiy
27-07-2010, 07:55
zalex_ua,

Вообщем, я сделал вот так, конвертирую в УТФ8 при помощи функции в vbs и кладу в temp файл, а затем этот temp файл читаю при помощи команды type

Call ConvertCharsetFile(InstalledApplications("."))
WScript.Quit 0


Function InstalledApplications(node)
Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE
Set oRegistry = GetObject("winmgmts://" _
& node & "/root/default:StdRegProv")
sBaseKey = _
"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstal l\"
iRC = oRegistry.EnumKey(HKLM, sBaseKey, arSubKeys)

For Each sKey In arSubKeys

sVersion= ""

iRC = oRegistry.GetStringValue( _
HKLM, sBaseKey & sKey, "DisplayName", sValue)

'get version
oRegistry.GetStringValue _
HKLM, sBaseKey & sKey, "DisplayVersion", sVersion


If iRC <> 0 Then
oRegistry.GetStringValue _
HKLM, sBaseKey & sKey, "QuietDisplayName", sValue
End If


If sValue <> "" and instr(sValue, "KB")=0 Then
'instr(sValue, "KB")=0 - to exlude KB-indexed Microsoft Patches




' Check if version is already in Displayname:
If sVersion <> "" then
' wscript.echo "svalue"&svalue&" "&"sversion"&sversion
If instr(sValue, sVersion)=0 then
sValue=sValue &" "&sVersion
End If
End If

If instr(InstalledApplications, sValue&vbCrLf)=0 then
'and instr(InstalledApplications, sValue&vbCrLf)=0 - to exlude possible dublicates


InstalledApplications = _
InstalledApplications & sValue & vbCrLf
End If
End If
Next

End Function




Function ConvertCharsetFile(input)
Const adTypeBinary = 1
Const adTypeText = 2
Const bOverwrite = True
Const bAsASCII = False

'Write to temp file
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists( "C:\usr\zabbix\uAllPrograms_temp.txt" ) Then objFSO.DeleteFile "C:\usr\zabbix\uAllPrograms_temp.txt"
Set objFile3 = objFSO.CreateTextFile("C:\usr\zabbix\uAllPrograms_temp.txt")
objFile3.WriteLine input
objFile3.Close

Dim oFS : Set oFS = CreateObject( "Scripting.FileSystemObject" )

Dim sFFSpec : sFFSpec = oFS.GetAbsolutePathName( "C:\usr\zabbix\uAllPrograms_temp.txt" )

Dim oFrom : Set oFrom = CreateObject( "ADODB.Stream" )
Dim sFrom : sFrom = "windows-1251"
Dim oTo : Set oTo = CreateObject( "ADODB.Stream" )
Dim sTo : sTo = "utf-8"

oFrom.Type = adTypeText
oFrom.Charset = sFrom
oFrom.Open
oFrom.LoadFromFile sFFSpec

oTo.Type = adTypeText
oTo.Charset = sTo
oTo.Open
oTo.WriteText oFrom.ReadText
oFrom.Close
If oFS.FileExists( sFFSpec ) Then oFS.DeleteFile sFFSpec
oTo.SaveToFile sFFSpec
oTo.Close
End Function

В zabbix_agentd.conf параметр выглядит как:
UserParameter=uAllPrograms, cscript.exe /nologo "C:\usr\zabbix\uAllPrograms.vbs" & type C:\usr\zabbix\uAllPrograms_temp.txt

zalex_ua
27-07-2010, 10:44
Вообщем, я сделал вот так, конвертирую в УТФ8 при помощи функции в vbs и кладу в temp файл, а затем этот temp файл читаю при помощи команды type

К утру :) я уже тоже начал думать что нужно изобретать велосипед чтобы передать информацию в utf8 прямо из оболочки cmd.
В интернете немерено информации с проблемами на тематику "cmd+utf8". И люди их как то решают вроди успешно, хотя у них совсем и другие случаи.
По поводу ключа /U для cmd - размышляли, пробовали что?
С переключением кодовой страницы chcp 65001 перед выполнением команд мидитировали? :)
Я так понимаю Юникод это же не совсем utf8 правильно? поэтому ключ /U особого интереса не представляет.
Короче зацепило все же побороть проблему, вплоть до смены интерпретатора cmd на .... гммм... нет вариантов:D

А может выводить как-то как не текст а как "двоичные данные" типа вот так:
.Type = 1
strConvert = .Read
Я в vbs совсем не силен, но такая мысль проскочила была.

gospodin.horoshiy
27-07-2010, 13:54
Ну я всякое пробовал, остановился на этом варианте, т.к. время небесконечно...А так вроде работает, хотя наверняка есть более красивые решения