Свойство сообщения Win32_NTLogEvent Проблема с вызовом процедуры FilSystemObject.Write

Я пишу скрипт для записи информации журнала событий в csv. Мой скрипт работал раньше. Но я изменил кое-что, что не должно повлиять на запись в csv. Я пытался писать в Unicode и в ASCII, основываясь на некоторых исследованиях, которые я провел в Интернете по этой проблеме. Ни то, ни другое не имеет значения. Странно то, что я использую тот же код позже в своем скрипте для записи других журналов (сначала я пишу системные журналы, затем я пишу журналы приложений и т. д.), и там он прекрасно работает. Код, который я использую, является временным, так как я не удосужился написать способ удаления возврата каретки из сообщений (что вызывает проблемы с импортом CSV в Excel). Так что это может исправиться, как только я это сделаю. Но похоже, что это более серьезная проблема. Вот сценарий до тех пор, пока он не перейдет к другим журналам:

Set wshShell = WScript.CreateObject( "WScript.Shell" )
strComputerName = wshShell.ExpandEnvironmentStrings( "%COMPUTERNAME%" )

strComputer = "."
strType = "Error"
strPath = "T:\IT resources\Event Logs\ErrorLog" & strComputerName & ".csv"

'Script to convert UTC to human readable. From Script Repository.

Function WMIDateStringToDate(dtmInstallDate)
    WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _
        Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _
            & " " & Mid (dtmInstallDate, 9, 2) & ":" & _
                Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _
                    13, 2))
End Function

'ForWriting is to write to file from start. ForAppending is to write to file from end of file.

constForWriting = 2
constForAppending = 8
constTristate = 0
boolUnicode = False
chrCarriageReturn = chr(13)
chrNewLine = chr(10)

Set objFSO = CreateObject("Scripting.FileSystemObject")


'This is so that cscript won't encounter a runtime error if the file already exists. Also so that it will write to the already existing file.

If objFSO.FileExists(strPath)=False Then

 Set objErrLog = objFSO.CreateTextFile(strPath,constForWriting,boolUnicode)
  objErrLog.Write "Type,"
  objErrLog.Write "Time Generated,"
  objErrLog.Write "Source Name,"
  objErrLog.Write "Event Code,"
  objErrLog.Write "Category,"
  objErrLog.Write "Message"
  objErrLog.Writeline
 strTimeMin = "01/01/1970/0:00:00"
'19700101000000.000000-480

 Else Set objErrLog = objFSO.OpenTextFile(strPath,constForAppending,constTristate)

'Only need this if it writes from the line the file ends on, as opposed to starting on a new line (which I expect it will).

  objErrLog.WriteLine

End If

Set objWMIService = GetObject("winmgmts:" _
 & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

'Querying Event Logs

Set colLoggedEvents = objWMIService.ExecQuery _
 ("SELECT * FROM Win32_NTLogEvent WHERE Logfile = 'system' AND "_
 & "Type = 'Error'")

'Type='Error' instead of "1" because it is a WQL query, I think. I believe that it is searching the entries in a database that reference the Win32_NTLogEvent objects. So I am searching the values in the database as opposed to the properties of the objects they reference. Or perhaps not. WHen I echo the type property of every object in colLoggedEvents, cscript outputs "Error". So maybe the I'm reading the SDK wrong? At least it seems to be working.

'This is a comparison function which tells where string 2 occurs in string 1. Starts at 1.

constStart = 1
constCompareType = 0

'This loop writes the information to a .csv.

For Each objEvent In colLoggedEvents

 If objEvent.Timegenerated > strTimeMin Then
  strTimeMin = objEvent.TimeGenerated
 Else
 End If
 objErrLog.Write objEvent.Type & ","
 objErrLog.Write WMIDateStringToDate(objEvent.TimeGenerated) & ","
 objErrLog.Write objEvent.SourceName & ","
 objErrLog.Write objEvent.EventCode & ","

 constExist=InStr(constStart,objEvent.Message,chrCarriageReturn,constCompareType)+InStr(constStart,objEvent.Message,chrNewLine,constCompareType)

  If constExist = 0 Then
   objErrLog.Write objEvent.Category & ","
   objErrLog.Write objEvent.Message

  Else
   objErrLog.Write objEvent.Category

  End If

 objErrLog.WriteLine

Next

Любая помощь будет принята с благодарностью.


person Adam Harvey    schedule 07.08.2014    source источник


Ответы (1)


  1. Избавьтесь от заблуждения, что код «может исправить сам себя»
  2. Укажите полную информацию об ошибке (номер, описание, идентифицированная строка) при задании вопроса.
  3. Предполагая, что вы получили ошибку «5 - Недопустимый вызов процедуры или аргумент» в строке, начинающейся с «objErrLog.Write», см. здесь для объяснения.
  4. Вы утверждаете, что протестировали вариант своего кода с использованием Unicode; вы этого не сделали, потому что:

Прототип .CreateTextFile:

object.CreateTextFile(filename:string[, overwrite:bool[, unicode:bool]])

Это противоречит вашему

objFSO.CreateTextFile(strPath,constForWriting,boolUnicode)

Прототип .OpenTextFile:

object.OpenTextFile(filename:string[, iomode:enum[, create:bool[, format:enum]]])

Это противоречит вашему

objFSO.OpenTextFile(strPath,constForAppending,constTristate)

Так что исправьте эти ошибки (сами!), протестируйте файл, действительно открытый для Unicode, и надейтесь, что предположение (3) верно.

Обновление комментариев:

Пожалуйста, обратите внимание на "Дайте полные сведения об ошибке (номер, описание, идентифицированная строка) при задании вопроса" в контексте:

Я получаю ошибку недопустимой процедуры после 68 членов colLoggedEvents, когда у меня есть файл в ASCII.

vs

Я получаю сообщение об ошибке при вызове метода OpenTextFile

Первое утверждение подразумевает, что 68-й член содержит символы, которые нельзя записать в режиме ASCII/ANSI. Действительно/правильно использование выходного формата Unicode устранит проблему, если журнал ошибок не содержит неверных данных.

Второй оператор указывает, что параметры методов .Open/CreateTextfile по-прежнему неверны. Вы изменили оба вызова на Unicode?

Обновление II:

Документы определяют

TristateTrue -1 Открывает файл как Unicode.

Ваш код неправильно использует:

constTristate = 1 
Set objErrLog = objFSO.OpenTextFile(strPath,constForAppending,boolCreate,constTristate) 

Свидетельство:

>> Set ts = goFS.OpenTextFile("error5.txt", 8, False, 1)
>>
Error Number:       5
Error Description:  Invalid procedure call or argument
>> Set ts = goFS.OpenTextFile("error5.txt", 8, False, -1)
>>
>> <-- no news are good news

Обновление комментария относительно TriStateTrue:

В документе VBScript говорится:

TristateUseDefault -2 Opens the file using the system default.
TristateTrue       -1 Opens the file as Unicode.
TristateFalse       0 Opens the file as ASCII.

Документ @Adam, на который ссылаются, относится к VBA; но без проверки я бы не стал доверять.

person Ekkehard.Horner    schedule 07.08.2014
comment
Да, я заметил, что забыл включить параметры создания. Что я сейчас исправил. Я торопился, потому что вчера это меня расстроило. Так что я пропустил этот вариант по ошибке. После устранения этой проблемы переход на юникод приводит к тому, что проблема появляется раньше. Я получаю ошибку недопустимой процедуры после 68 членов colLoggedEvents, когда у меня есть файл в ASCII. Но в Unicode это не проходит. Кроме того, я не имел в виду, что проблема решится сама собой. Я имел в виду, что это можно исправить, сделав то, что я сказал. Потому что я бы все равно изменил соответствующий раздел кода. - person Adam Harvey; 07.08.2014
comment
Я хотел сказать, что получаю сообщение об ошибке при вызове метода OpenTextFile. Но я случайно нажал Enter раньше, чем собирался. Итак, мой ответ опубликован, и я слишком долго редактировал его. Я проверил все параметры OpenTextFile, и кажется, что теперь все должно работать. У меня есть: «Параметры для OpenTextFile constForAppending = 8 boolCreate = False constTristate = 1 Set objErrLog = objFSO.OpenTextFile (strPath, constForAppending, boolCreate, constTristate) - person Adam Harvey; 07.08.2014
comment
Я определенно изменил оба на юникод. Метод createtextfile читается как Set objErrLog = objFSO.CreateTextFile(strPath,boolOverwrite,boolUnicode) с boolOverwrite=False и boolUnicode=True. Метод OpenTextFile читается как Set objErrLog = objFSO.OpenTextFile(strPath,constForAppending,boolCreate,constTristate) с constForAppending=8, boolCreate=False и constTristate=1. Я просматривал это снова и снова, чтобы убедиться, что у меня есть правильные ценности. Но это ошибка при вызове OpenTextFile. Вызов CreateTextFile в порядке. - person Adam Harvey; 08.08.2014
comment
@AdamHarvey - см. Обновление II. - person Ekkehard.Horner; 08.08.2014
comment
Что ж, смена знака на тристате исправила это. Так что спасибо за помощь. Однако действительно странно то, что в MSDN написано «положительно 1». Я только что дважды проверил, чтобы убедиться, что я не ошибся 20 раз. Я просматриваю эту страницу (msdn.microsoft .com/en-us/library/aa265347(v=vs.60).aspx). Какую документацию вы используете? - person Adam Harvey; 11.08.2014
comment
Я просто смотрел на этот старый пост и понял, что я должен обновить его. Я не уделял должного внимания заголовку в MSDN и просто читал не ту страницу. Так что не стоит паниковать из-за опечаток. Хотя я признаю, что видел некоторые из них раньше, которые являются законными опечатками. - person Adam Harvey; 25.10.2014