JoshuaKo Ответов: 2

Получение ошибки "неправильная функция" в функции на конкретных компьютерах


Использование vb.NET я использую XmlDocument чтобы загрузить, измените и сохраните существующий XML-файл. Загрузка и модификация работают, но я получаю ошибку "Неправильная функция" при попытке сохранить XML-файл. Я получаю эту ошибку как сообщение от try catch. Даже когда я комментирую свой код в середине загрузки и сохранения, я все равно получаю эту ошибку...

Целевая платформа: .NET Framework 4.5.
Тип приложения: приложение Windows Forms

Это проблема ПК, так как она действительно работает на некоторых компьютерах с Windows, но не на других. Я попытался сравнить несколько вещей, но я не уверен, что искать для сравнения.

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

Заранее благодарю вас!

Код:
Imports System.Xml
Dim ShipXMLDocument As XmlDocument = New XmlDocument()
ShipXMLDocument.Load(FilePath)
Dim objNodeList = Nothing

objNodeList = ShipXMLDocument.DocumentElement.SelectNodes("//ShipShipment/DataArea/Shipment/Header/Parties/Party")

If objNodeList.Count > 0 Then
	For i = 0 To objNodeList.Count - 1
		If objNodeList.Item(i).FirstChild.InnerText <> "SHIPPER" Then
			For ChildNode = 0 To objNodeList.Item(i).ChildNodes.Count - 1
				If objNodeList.Item(i).ChildNodes.Item(ChildNode).Name = "Name" Then
					objNodeList.Item(i).ChildNodes.Item(ChildNode).InnerText = "Tester McTestingstein"
				ElseIf objNodeList.Item(i).ChildNodes.Item(ChildNode).Name = "EmailAddress" Then
					objNodeList.Item(i).ChildNodes.Item(ChildNode).InnerText = "Testing@Testing.com"
				End If
			Next
		End If
	Next
End If

ShipXMLDocument.Save(FilePath)


Я получаю это как трассировку стека:
Цитата:
в корпорации Microsoft.На языке VisualBasic.CompilerServices.Символы.Контейнер.InvokeMethod(Метод TargetProcedure, Аргументы Object [], Boolean[] CopyBack, Флаги BindingFlags)
в корпорации Microsoft.На языке VisualBasic.CompilerServices.NewLateBinding.CallMethod(контейнер BaseReference, строка Имяметода, объект[] Аргументы, строка[] ArgumentNames, тип[] помощью, логические[] CopyBack, флаг bindingflags InvocationFlags, логическое ReportErrors, ResolutionFailure&амп; отказ)
в корпорации Microsoft.На языке VisualBasic.CompilerServices.NewLateBinding.ObjectLateCall(Экземпляр Объекта, Тип Type, String MemberName, Аргументы Object [], String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
в корпорации Microsoft.На языке VisualBasic.CompilerServices.NewLateBinding.LateCall(Экземпляр Объекта, Тип Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
в Apollo_Shipping.Функции.XML_ScrubContactInformation(Object FilePath) в C:\Temp\Send тестовая отгрузка\отправить тестовую отгрузку\функции.vb:строка 584


Что я уже пробовал:

- Запуск этого кода на другом компьютере с Windows.
- Комментируя мой код в середине загрузки XML и сохранения XML.

Christian Graus

Если он работает на некоторых компьютерах, а не на других, это означает, что какой-то библиотеки, которую использует этот код, нет. Можете ли вы проверить, какие версии .NET установлены на этих компьютерах (хотя XmlDocument был там с самого начала, как я думал)

Для i = 0 в objNodeList.Количество - 1


VB-это довольно дерьмово, но если вам нужен -1, то это действительно очень дерьмово. - Вы уверены?

JoshuaKo

Христианин,

Спасибо за ваш комментарий. Пожалуйста, обратите внимание, что даже когда я комментирую свой код в середине загрузки XML и сохранения XML, я все равно получаю ту же ошибку.

При использовании (Get-ItemProperty "HKLM:SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full").Релиз в PowerShell я получаю тот же ответ: "528040". Я получил этот запрос от https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed#ps_a

Christian Graus

Я отправил более полный ответ в качестве ответа.

Очевидно, что если ваш код сохранения взорвется, то код редактирования не имеет значения. Почему бы не попробовать то, что я предложил вместо этого?

JoshuaKo

Я постараюсь использовать файл.SaveAllText, но я хотел попытаться выяснить, в чем заключается первопричина, а не просто применить обходной путь.

Есть ли способ определить, какая библиотека используется, чтобы подтвердить, есть ли эта библиотека или повреждена?

Christian Graus

Согласно документам, здесь нет никакой внешней библиотеки, так что все это кажется странным. TBH я ожидаю, что вы скажете, что это также не работает, и проблема в чем-то другом, как вы пытаетесь написать защищенный файл.

JoshuaKo

- Вы правы. Я попробовал использовать файл.WriteAllText(Путь К Файлу, ShipXMLDocument.InnerXml), и я получаю нижеприведенную трассировку стека:
в System.IO.__ошибка.WinIOError(код ошибки Int32, строка maybeFullPath)
в System.IO.FileStream.Метод init(string путь, режим filemode необходимо открыть флагами fileaccess, int32 и прав, логическое useRights, поделиться обменник, типа int32 значение bufferSize, варианты FileOptions, в разделе security_attributes secAttrs, строки msgPath, логическое bFromProxy, логическое useLongPath, логическое checkHost)
в системе.ИО.Хранилище FileStream..конструктор(string путь, режим filemode необходимо открыть флагами fileaccess, поделиться обменник, типа int32 значение bufferSize, FileOptions варианты, строки msgPath, логическое bFromProxy, логическое useLongPath, логическое checkHost)
в System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
в системе.ИО...Конструктор модулю записи StreamWriter(Path строка, булево добавить, кодирования, кодировки, типа int32 значение bufferSize, логическое checkHost)
в файле System.IO.InternalWriteAllText(путь к строке, содержимое строки, кодировка кодировки, логическая проверка)
в файле System.IO.WriteAllText(путь к строке, содержимое строки)
в Apollo_Shipping.Функции.XML_ScrubContactInformation(Object FilePath) в файле \\xxxx\Functions.vb:строка 604

Эта трассировка стека дает вам лучшее понимание?

Что касается вопроса "Вы пытаетесь написать защищенный файл", то я могу успешно изменить этот XML-файл в блокноте на компьютере, на котором возникла эта проблема. Также обратите внимание, что под моим логином на другом компьютере эта функция работает отлично.

Christian Graus

Например. если бы вы открыли XML в другой программе, он был бы заблокирован. Ошибка, а не трассировка стека, поможет. Попробуйте записать в файл, который, как вы знаете, не существует.

JoshuaKo

Чтобы быть ясным, я заменил " ShipXMLDocument.Save(FilePath)" with "File.WriteAllText(Путь К Файлу, ShipXMLDocument.InnerXml)".

JoshuaKo

Я смог создать новый файл с моими изменениями. Так что же это значит? Как я могу писать в один и тот же файл?

Christian Graus

Ваша проблема заключается в том, что файл заблокирован. Я подозреваю, что класс XMlDocument действительно заблокировал его. Если у него есть метод Dispose, поместите его в блок using. Сохраните XML-файл в переменной, закройте документ, а затем сохраните его с помощью только что написанного кода

JoshuaKo

Нет никакого метода dispose/close. Кроме того, GC.Collect() также не работает перед сохранением.

Christian Graus

Хорошо, тогда просто закройте файл. СБОРЩИК МУСОРА.Собирать деньги-это почти всегда плохая идея. Если нет избавления, то нет и проблемы. Единственное другое дело если у вас есть файл открытый в Word например во время работы над кодом

JoshuaKo

"Если нет избавления, то нет и проблемы", но это моя проблема. Мне нужно изменить и сохранить тот же файл, и я не знаю, как отпустить блокировку. Я пытался:

Dim tempXMLText As String = ShipXMLDocument.InnerXml
ShipXMLDocument = Ничего
Файл.WriteAllText(путь к файлу, tempXMLText)

Но и это не сработало.

Самое странное во всем этом то, что это прекрасно работает на моем компьютере, но не на пользователях.

Christian Graus

Вы делали ShipXmlDocument?Близко, как я сказал?

Он не может работать на любом компьютере, если файл заблокирован. Если это работает на некоторых, это другая программа, которая держит файл открытым.

https://alternativeto.net/software/wholockme/

Эти программы помогут Вам разобраться что такое блокировка файла

JoshuaKo

Нет никакого документа ShipXmlDocument.Метод close... :(

Я посмотрю на этот url-адрес, но разве он не скажет мне, что я блокирую его своей программой?

Christian Graus

Я так не думаю. Ваш код везде одинаков. Поэтому я думаю, что у вас есть программа, блокирующая его на некоторых машинах

JoshuaKo

Хорошо, спасибо, тогда это займет некоторое время. Спасибо Вам за всю вашу помощь до сих пор.

Christian Graus

Не беспокойтесь :)

2 Ответов

Рейтинг:
2

Christian Graus

mports System.Xml
Dim ShipXMLDocument As XmlDocument = New XmlDocument()
ShipXMLDocument.Load(FilePath)
Dim objNodeList = Nothing

objNodeList = ShipXMLDocument.DocumentElement.SelectNodes("//ShipShipment/DataArea/Shipment/Header/Parties/Party")


В этом нет никакого смысла. Почему бы просто не установить его значение в первой строке?
If objNodeList.Count > 0 Then
	For i = 0 To objNodeList.Count - 1


Я сомневаюсь, что счет - 1 верен. Кроме того, вы можете сделать foreach в списке узлов вместо того, чтобы искать их по индексу

If objNodeList.Item(i).FirstChild.InnerText <> "SHIPPER" Then
    For ChildNode = 0 To objNodeList.Item(i).ChildNodes.Count - 1
        If objNodeList.Item(i).ChildNodes.Item(ChildNode).Name = "Name" Then


Я совершенно уверен, что вы могли бы использовать xpath, чтобы исключить "Грузоотправитель" в качестве значения.

objNodeList.Item(i).ChildNodes.Item(ChildNode).InnerText = "Tester McTestingstein"
            ElseIf objNodeList.Item(i).ChildNodes.Item(ChildNode).Name = "EmailAddress" Then

Такой код быстро превращается в спагетти. Используйте оператор switch, чтобы не работать с различными узлами. Кроме того, если вы смотрите на имена узлов, а не на значения, вам было бы лучше иметь две коллекции узлов на этом уровне, по одной для каждого узла, с которым вы хотите работать
					objNodeList.Item(i).ChildNodes.Item(ChildNode).InnerText = "Testing@Testing.com"
				End If
			Next
		End If
	Next
End If

ShipXMLDocument.Save(FilePath)


Если это взрывается, я бы попробовал сохранить XML в строке и использовать файл.SaveAllText, чтобы сохранить его и посмотреть, работает ли это


Richard Deeming

Count - 1 правильно. ГЛ. (и VB.NET) действительно ли это дерьмо. :)

Для...Следующая Инструкция - Visual Basic | Microsoft Docs[^]

Рейтинг:
0

JoshuaKo

Обновление: проблема была в антивирусе.