Error ret null

Возможные ошибки и способы их решения Техподдержка-партнеры aQsi - онлайн кассы для вашего бизнеса по 54-фз

Ошибки в кассовом чеке (чек-коррекции)

В общем случае в ФФД 1.05 ошибки исправляются чеком возврата, в ФФД 1.1 и 1.2 — чеком коррекции. А если кассу не применили при расчете, то нужен чек коррекции, и не имеет значения по какому формату работает ККТ.

Согласно нормативно-правовым документам: Приказ ФНС России от 14.09.2020 № ЕД-7-20/662@ и п.4 статьи 4.3 54-ФЗ.

Для исправления ошибки в чеке – неправильная СНО / НДС / цена товара

  • Необходимо сформировать чек возврата абсолютно идентичный неправильному чеку прихода. В случае, если расчет был картой и невозможно сразу пробить возврат – следует оформить возврат через нефискальный приход и фискальный возврат. Способ оплаты “безналичные”.
  • Необходимо сформировать новый кассовый чек прихода с указанием правильных реквизитов. Даже если оплачивали раньше картой, необходимо пробить приход как “безналичный”.
  • Необходимо сформировать пояснительную записку с описанием ФП и ФД некорректного чека, указать причину, по которой ошибку исправляли, указать ФД и ФП нового правильного чека прихода. Эту пояснительную в любой форме передать в ФНС, либо через лк фнс, либо отнести в отделение.

В случае, если ККТ при расчете не применили – формируется чек-коррекции.

Касса не заряжается при использовании переходника aQsi Hub

  • Опустить шторку / Спец возможности,
  • Включить пункт OTG HUB & Параллельная зарядка.
  • Подключить aQsi Hub к aQsi кассе через USB Type-C.
  • Подключить патч-корд Ethernet, второй конец подключить к источнику, раздающему Ethernet (интернет-розетка, маршрутизатор и прочее).
  • Если после этого зарядка не идет, попробуйте использовать другой провод питания

Ошибка 116 : ошибка файлового ввода вывода

Данная ошибка может возникать по двум причинам:

  • Заполнена память. Необходимо очистить память на кассе, перезагрузить (reboot) и проверить работоспособность.
  • Не обновлено приложение MCU. Настройки/ Тех.обслуживание ККТ / Доп.операции / Принудительное обновление MCU. Перезагрузить кассу (reboot). Проверить работоспособность.

В случае, если ошибка сохраняется- необходимо обратиться в службу поддержки.

Ошибка 20 ФН Ограничение ресурса ФН

Ошибка говорит о том, что данные не передаются в ОФД и налоговую. Если данные не уходят в течение 30 дней – касса блокируется (ошибка 20).

  • Возможно, смена не была вовремя закрыта: Необходимо изменить время на кассе (опускаете шторку настроек Android на кассе движением пальца сверху вниз, открываете настройки – Дата и время). Установите значения даты и времени на время, когда была открыта последняя смена.Далее зайдите в настройки в главном меню – Техническое обслуживание ККТ – Дополнительные операции – Дата и время – установить системное (нажимаем на надпись системное).Закройте смену и верните корректное время по такому же алгоритму.
  • Проверьте стабильность интернета (без подключения к сети – чеки не отправляются).
  • Проверьте подключение к ОФД:
    Вам нужно на кассе зайти в Настройки / тех. обслуживание ККТ / подключение к ОФД. Далее нужно сверить настройки и исправить их, если они неверные. (https://kassopttorg.ru/questions/12732/  – список параметров)
    IP —
    Порт —
    Таймаут — 30
  • Если все установлено корректно, то нужно направить клиента в ОФД, возможно, что услуги в ОФД не оплачены.

Ошибка Notimplemented при закрытии смены

Необходимо зайти на кассе в Настройки / Основные настройки / Смены / “Перезагрузка рабочих ключей при закрытии смены” – выкл.

Ошибка QR кода маркировки в ЛК на вкладке Товароучет

Необходимо открыть раздел в ЛК – Настройки / Общее / Учёт кодов маркировки – выкл.

Ошибка 126 в чеке коррекции.

Ошибка 126 говорит о том, что поле “Номер документа основания” заполнено некорректно.

Если тип коррекции “Самостоятельно”, то номером документа является порядковый номер пояснительной (объяснительной) записки.

Ошибка 7 ФН (подходит и для ошибки 23)

Опустите шторку Андроида / Шестеренка / Дата и время / Дата и время в сети — выкл, Часовой пояс — выкл. / Проверьте время корректное или нет. Если время некорректное – исправьте.

Закройте смену (если она была открыта).

Далее зайдите в Настройки / Тех.обслуживание ККТ / Доп.операции / Дата и время —нажмите на синее поле “установить системное”.

В этом же меню нажмите «открыть смену» (при необходимости нажмите 2 раза).

Ошибка уйдет.

Примечание! В случае, если ошибка 7 ФН сохраняется, проверяем Дату последнего ФД в информации об устройстве. Если Дата последнего ФД установлена в будущем времени, то клиент не сможет пробивать чеки, пока на кассе не наступит эта дата.

Ошибка Read time out

Зайдите в Настройки — Тех. обслуживание ККТ — Доп. операции — Отключить печать КЯ. Закройте и откройте смену.
Затем перезагрузите кассу.

Проверьте на наличие ошибки. Если ошибка сохраняется – обратитесь в поддержку Акси.

Ошибка принтера Paper Exception Error ret null

  • Войти в настройки/ техническое обслуживание ККТ/ дополнительные операции/ нажать на “Принудительное обновление MCU”.
  • После обновления MCU нажать на “Отключить печать КЯ”.

Если ошибка сохраняется – необходимо запросить обновления в технической поддержке указав наименование ошибки.

Ошибка 51 общая

  • Убедитесь, что на кассе установлена корректная СНО в разделе Настройки / Основные / Чеки / СНО по умолчанию
  • Пройдите перефискализацию повторно. Зайдите в раздел мастер фискализации, с 1 шага проверьте все данные, обратите внимание на СНО. На 2 шаге внимательно заполните поля Адрес и Место расчетов. На 4 шаге обратите внимание на поле «сведения о применении кассы», либо ничего не заполняйте, либо выберите нужный пункт. Завершите перефискализацию с причиной «изменение настроек ККТ». Email отправителя чека – заполните электронный адрес почты нужного ОФД. Пример перерегистрации по инструкции – https://aqsi.ru/support/pereregistraciya-kassyi-c-envd-na-usn/
  • Проверьте способ и предмет расчета. Зайдите в раздел База товаров, выберите одну из товарных позиций, прикоснитесь на 2 секунды — «изменить».
  • Проверьте, чтобы в поле предмет расчета у Вас был «товар» (если продаете товары) или «услуга» (если оказываете услуги).
    Также обратите внимание на способ расчета — должен быть полный расчет.
  • После выполнения пункта 1-3 зайдите в Настройки / Тех.обслуживание ККТ / Дополнительные операции / Перезагрузить кассовое ядро.
    При нажатии звукового и видимого эффекта не будет.
  • Попробуйте оформить чек из истории или выбить новый.

Примечание: При применении ОСН + ФН на 36 месяцев, оформлять на кассе можно ТОЛЬКО УСЛУГИ!

Ошибка при сохранении в ФН

Ошибка говорит о том, что чек не сохранился в ФН и не был отправлен в ОФД и ФНС.

Вам необходимо:

  • Отключить фискальный накопитель, затем плотно подключить его и перезагрузить кассу (команда reboot).
  • Далее зайти в Настройки / Тех.обслуживание ККТ / Доп.операции / Перезагрузить кассовое ядро (при нажатии ничего не произойдет, видимых эффектов не будет).
  • После этого зайти в историю чеков, нажать на чек с надписью “ошибка при сохранении” и нажать снизу “оформить чек”.

Также проверьте в Настройках / Основные настройки / Чеки / СНО по умолчанию — указана ли верная система налогообложения.

Если ошибка сохраняется, необходимо найти причину или уточнить код ошибки. Действия, соответственно, будут иные.

Окно “в работе приложения кассовое ядро …” при включении кассы

Данное сообщение не является ошибкой. Это информация о том, что при запуске ККТ кассовое ядро не успело загрузиться.
Вам необходимо закрыть уведомление и войти в кассу.

Рекомендуем зайти в Настройки / Тех. обслуживание ККТ / Доп. операции / Перезагрузить кассовое ядро. (видимых эффектов не произойдет).
Далее сделать перезагрузку ККТ (Reboot).

Ошибка Parcelable encountered ClassNotFoundException reading a Serializable object (name= re.aqsi.commons.exception.ShiftAlreadyOpenException)

Ошибка при открытии смены означает, что смена уже находится в состоянии “открыта”.

Необходимо зайти в Настройки / Тех. обслуживание ККТ / Доп. операции / Закрыть смену. Затем необходимо повторно открыть смену.

Ошибка “Исчерпан ресурс КС” или ошибка 18, когда закончился ФН

Эта ошибка говорит о том, что у клиента закончился ФН и нужно его заменить.
Но у клиента могла остаться открыта смена.

  • Движением пальца сверху вниз, откройте шторку настроек системы. Далее перейдите в «Дата и время». Установите значения даты и времени, равное последнему открытию смены.
  • В главном меню перейдите в Настройки -> Техническое обслуживание ККТ -> Дополнительные операции -> Дата и время -> установите системное (нажать на «системное»).
  • Нажмите «Закрыть ФН».

Неотправленных документов в разделе Настройки / Тех. обслуживание ККТ / Информация об устройстве – должно быть 0.

Ошибка в ЛК Orange data – Fiscalization for device … not found. / cashbox fiscalized cloudly

Для того, чтобы избавиться от ошибки Вам необходимо выполнить следующее:

Настройки / Мастер фискализации / с использованием ФН — далее / на Шаге № 2 уберите галочку «разъездная торговля» , проверьте корректность остальных полей.

Дойдите до Шага № 4:

– выберите пункт перерегистрация с причиной «изменение настроек ККТ»;

– email отправителя — адрес Вашего ОФД, выбранного на шаге № 3;

– сведения о применении ККТ — для расчетов в сети «Интернет» — поставьте галочку;

– нажмите «проверка параметров» — распечатается чек;

– нажмите «зарегистрировать кассу» — распечатается чек;

– на экране нажмите «я ввел данные», затем нажмите «готово».

После этого необходимо сгенерировать токен в личном кабинете aQsi.

Инструкция по ссылке — https://aqsi.ru/support/fiskalizaciya-chekov-orangedata-internet-magazinyi/

– в личном кабинете Акси вкладка Настройки / Интеграции / Фискализация чеков на aQsi 5 из Оранж Дата / сгенерировать токен (ключ) / скопируйте токен;

– открыть ЛК Оранж Дата / раздел Услуги / вставьте токен(ключ) / сформируйте счет без ошибки.

Эквайринговое ядро не отвечает по тайм-ауту.

Если эквайринговое ядро не отвечает по таймауту, нужно нажать внизу экрана “Попробовать еще раз”.
Это не ошибка, а сообщение о том что касса не может достучаться до банковского хоста.
Можно перезагрузить кассу и попробовать еще раз.

Ошибка “Введены некорректные данные” при фискализации

Если касса при фискализации выдает ошибку “Введены некорректные данные” необходимо:

  • Убедиться в правильности заполнения всех полей;
  • Выполнен ли вход в кассу под пользователем Администратор.

Ошибка “Некорректный РНМ” при фискализации (перефискализации).

Если касса при фискализации выдает ошибку “Введен некорректный РНМ” необходимо:

  • Проверить подключение ФН к кассе;
  • Войти в настройки/ техническое обслуживание ККТ/ и проверить, записан ли серийный номер кассы в строке ЗН ККТ.
  • Если серийный номер в информации об устройстве отсутствует, нужно войти в Настройки/ тех обслуживание/ ввод заводского номера/ ввести заводской номер кассы в строку и нажать “Записать”.
  • Убедиться в правильности заполнения поля ОГРН на шаге 1.
  • Убедиться в правильности заполнения полей “Сведения о пользователе” на шаге 2.
  • Убедиться в правильности заполнения поля Email отправителя чека – электронный адрес ОФД.
  • Если все данные введены корректно, то необходимо обратиться в техническую поддержку.

Ошибка connection refused

Данная ошибка говорит о том, что касса не подключена к сети интернет. Для устранения ошибки необходимо подключить ее к сети интернет через WI-FI либо через сим-карту.

Ошибка missingdata при оплате банковской картой

Если появилась данная ошибка, то нужно зайти в НастройкиТехническое обслуживание ККТДополнительные операцииЗагрузить конфигурацию эквайрингового ядра.
Существует два варианта:

  • появляется сообщение «Успешно», это значит, что конфигурация в кассу загружена, а ошибка возникает из-за плохого интернет соединения.
  • появляется ошибка «при загрузке конфигурации произошли ошибки, код: missingdata», в данном случае для решения проблемы вам необходимо обратиться в техническую поддержку.

Заранее уточните детали операции, ИНН организации, ЗН кассы, сумма оплаты, время, вид карты, прикладывали или вставляли чипом.

Не нажимается кнопка «Регистрация кассы», только галка «Перерегистрация» (при первичной фискализации кассы)

Данная ошибка говорит о том, что касса уже была зарегистрирована. Необходимо:

Проверить статус в ЛК / проверить История чеков /проверить смены / проверить печатается ли отчет о фискализации.
Если касса б/у – необходимо сделать полный сброс в Настройках /Тех. обслуживание ККТ / Доп. операции / Полный сброс.

В случае неуспеха – отправьте запрос в техническую поддержку на переустановку РМК.

Ошибка при оплате иностранной картой

Чтобы касса принимала карты иностранных банков, необходимо отправить дополнительный запрос в aQsi. Для этого необходимо:

  • запросить ИНН организации;
  • уточнить вид деятельности;
  • уточнить размер среднего чека для применения иностранной карты (в переводе на рубли);
  • отправить запрос в поддержку (info@aqsi.ru) на подключение лимита по приему иностранных карт, указав информацию из пункт 1-3.

Примечание: услуга для клиента бесплатная.

Касса не подключается к сети Wi-fi

Необходимо проверить возможные ограничения сети:

  • Опустить шторку Андроид / нажать и удерживать значок “батареи” / Режим энергосбережения – отключить
  • Опустить шторку Андроид / Шестеренка / Передача данных / Экономия трафика – выкл.
  • Опустить шторку Андроид / Шестеренка / Передача данных / Ограничения трафика – выкл.
  • Проверить актуальность времени в шторке / Шестеренка / Дата и время.

Ошибка «Отсутствует чековая лента», либо «Отсутствует фискальный накопитель»

При возникновении данной ошибки, необходимо:

  • Не отключая устройство, отсоединить от него фискальный накопитель и аккумулятор, в последовательности (Фискальный накопитель/Аккумулятор).
  • Подключить фискальный накопитель и аккумулятор обратно к устройству, в последовательности (Аккумулятор/Фискальный накопитель).
  • После включения аппарата ошибки не будет.

Касса печатает неверную СНО

Зайдите в “Настройки” / “Мастер фискализации”, проверьте пошагово корректность введенных данных (СНО выбирается на 1 шаге), на 4 шаге поставьте точку на «перерегистрация кассы», в причинах укажите «изменение настроек ККТ», после перефискализируйте кассу.

Примечание: Настройки мастера фискализации необходимо проводить только при закрытой смене.

После заставки aQsi касса выключается

Для того чтобы включить кассу, необходимо:

  • Подключите к кассе провод зарядки и начинайте включать аппарат, после того как аппарат начнёт включаться выньте из него аккумулятор.
  • Отключите провод зарядного устройства, вставьте аккумулятор и включите.
  • После этих действий войдите в Настройки/ техническое обслуживание ККТ/ дополнительные операции/ и нажмите «Принудительное обновление MCU”.

Ошибки 1002, 211. Ошибка печати

Для устранения данных ошибок, необходимо:

  • Войти в настройки/ техническое обслуживание ККТ/ дополнительные операции/ нажать на “Принудительное обновление MCU”.
  • После обновления MCU нажать на “Отключить печать КЯ”, ошибка уйдет.

Ошибки 115, 77 и 94 (общие) после обновления кассы

Выполните, пожалуйста, следующую инструкцию:

  • Зайдите на кассе в Настройки / тех. обслуживание ККТ / доп. операции и нажмите на «Принудительное обновление МСЮ». Закройте смену и откройте ее снова.
  • Перезагрузите кассу
  • Зайдите в Настройки / Основные настройки / Чеки и проверьте, что там указана верная система налогообложения.
  • Далее зайдите в «Историю чеков» и оформите повторно чек с ошибкой.

Ошибка 178: Код ошибки 32h(50) от ФН: Запрещена работа с маркированными товарами.

Данная ошибка возникает в момент сканирования маркированного товара при продаже, если касса не фискализирована с галочкой “при приеме маркированного товара” в Мастере фискализации.

Нужно закрыть смену и фискализировать кассу правильно.

Маркированный товар

В форматах ФФД 1.05 и 1.1, в бумажном чеке рядом с маркированным товаром ставится префикс [M]. В чеках ФФД 1.2 у префикса появились вариации:

(М+) – проверка в фискальном накопителе и системе маркировки прошли успешно. Для покупателя это значит, что он точно купил оригинальный маркированный товар.

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

(М-) хотя бы одна проверка завершилась провалом. Для покупателя это значит, что с товаром точно что-то не так.

Настройки / Основные настройки / Чеки / Режим проверки маркировки

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

Ошибка 33h (51) от ККТ: некорректные параметры в команде <0x0033005B: предварительно необходимо сформировать «Отчёт о текущем состоянии расчётов”> при фискализации / перефискализации

При возникновении данной ошибки необходимо снять отчет о текущем состоянии расчетов.

Далее в Мастере фискализации необходимо обязательно выбрать ИНН организации из выпадающего списка, проверить правильность всех введенных данных на каждом шаге Мастера фискализации.

Примечание: Код ошибки 33h (51) от ККТ: передает причину ошибки в самом запросе. Например, код ошибки  33h (51) от ккт: некорректные параметры в команде <0x0033005B: предварительно необходимо сформировать  “Отчёт о текущем состоянии расчётов”> – для устранения требуется сформировать отчет, ошибка уйдет.

Ошибка 162. Код ошибки 34h(52) от ФН: Работа с маркированными товарами временно заблокирована

Для устранения ошибки необходимо проверить и указать корректные данные для подключения к ОФД и настройки ОИСМ.

– Зайдите в раздел Настройки / Тех. обслуживание ККТ / Подключение к ОФД – Проверьте данные согласно вашему ОФД по ссылке  https://kassopttorg.ru/questions/12732/

Ошибка 3005 при оплате картой.

Ошибка дубля транзакции. Необходимо запросить информацию об успешности платежа в поддержке aQsi, отправив запрос на почту info@aqsi.ru с указанием ИНН, суммы и времени платежа.

Ошибка 3004 при оплате картой.

Необходимо запросить у клиента информацию:

  • ИНН
  • Сумма и время транзакции
  • Вид карты
  • Способ оплаты (nfc / чип)

Передать информацию в aQsi для уточнения причины ошибки в Банке.

Содержание

  1. Проблемы aQsi и их решения
  2. Заказ долго не появляется в списке отложенных
  3. Оплата на кассе прошла, а в Продуман статус Выполняется
  4. Признак Агент не печатается
  5. Ошибка «Service does not exist in loaded JCL registry» на кассе AQsi 5 — Как исправить?
  6. Возможные ошибки и способы их решения

Проблемы aQsi и их решения

Мы подготовили список часто случающихся проблем с aQsi и описали их решение

Схема обмена данных

Заказ долго не появляется в списке отложенных

Если в личном кабинете Продуман у вас написано «Ожидание оплаты на смарт-терминале», а заказ так и не появился на aQsi, значит нарушена синхронизация кассы aQsi с их облаком https://lk.aqsi.ru/

Зайдите в ЛК aQsi в список касс, и нажмите на иконку повторной синхронизации.

Облако aQsi попробует заново связаться с кассой и отправить на нее заказ.

Если ситуация не изменилась перезагрузите кассу или роутер, попробуйте кассу подключить к мобильному интернету на телефоне.

В случае, если описанные выше методы не помогают, обратитесь в поддержку aQsi

через личный кабинет aQsi раздел «Связаться»

Укажите тему проблемы Заказ в ЛК aQsi есть, а на кассе в отложенных не появляется .
Добавьте к обращению № заказа и серийный номер кассы (на обратной стороне 16 цифр)

Оплата на кассе прошла, а в Продуман статус Выполняется

Касса может не выгрузить все данные по чеку в облако с первого раза. Пример такой ситуации ниже (чек выгрузился, но список оплат так и не прогрузился).

Чтобы облако повторно запросило данные из кассы, найдите заказ в ЛК aQsi в разделе Заказы по номеру и нажмите на иконку повторной синхронизации. Информация будет прогружена в облако aQsi (сверху в блоке списка оплат появится способ оплаты), и вскоре статус обновится в Продуман.

В случае, если описанные выше методы не помогают, обратитесь в поддержку aQsi

через их личный кабинет «Связаться»

Укажите тему проблемы Чек пробит по заказу, но в облако aQsi нет списка оплат .
Добавьте к обращению № заказа и серийный номер кассы (на обратной стороне 16 цифр)

Признак Агент не печатается

Производитель кассы на прошивке, поддерживающей ФФД 1.2, убрал печать признака «Агент» и данных принципала, а также не предоставил возможность управления печатью этого реквизита. Эти данные доступны только в электронной форме чека.

Для запроса данной функции оставьте обращение производителю кассы на почту info@aqsi.ru

Тема: Отсутствует признак агента на ФФД 1.2

Текст: На прошивке ФФД 1.2 не печатается признак «Агент» и данные принципала. Просим включить печать данных реквизитов.

Источник

Ошибка «Service does not exist in loaded JCL registry» на кассе AQsi 5 — Как исправить?

Если возникает ошибка «Service does not exist in loaded JCL registry» и (или) в уведомлениях вылезает сообщение «Объем встроенной памяти недостаточен», нужно удалить log файлы системы. Для этого нужно:

  1. Развернуть шторку(панель уведомлений),нажать кнопку настроек(иконка шестеренки)
  2. В списке настроек найти и нажать Хранилище(откроется Внутренний общий накопитель)
  3. В Внутренний общий накопитель убедиться что память кассы действительно заполнено и нажать Открыть(обычно в конце списка)
  4. В открывшемся окне нажать на кнопку поиска (иконка лупы), поменять раскладку клавиатуры на латиницу (нажать кнопку с глобусом слева от кнопки «Пробел»), вбить в поиск слово log и нажать кнопку найти(иконка лупы справа от кнопки «Пробел»)
  5. Удалить все найденные файлы(нажать на файл и подождать пока не появится меню выбора действий и нажать кнопку удалить(иконка корзины))
  6. Перезагрузить кассу. После удаления log файлов память кассы должна освободиться. Если этого не произошло,нужно проверить память кассы на наличие других объемных файлов которые могут заполнить память.

Прочитали статью, но не смогли устанить ошибку? С радостью помогу Вам в решении проблемы!

Копирование «некопируемой» электронной подписи(ЭП) с Рутокена Lite.

Настройка компьютера для работы с ЭП от 500 руб.

Можете связаться со мной по Telegram.

Источник

Возможные ошибки и способы их решения

Ошибки в кассовом чеке (чек-коррекции)

В общем случае в ФФД 1.05 ошибки исправляются чеком возврата, в ФФД 1.1 и 1.2 — чеком коррекции. А если кассу не применили при расчете, то нужен чек коррекции, и не имеет значения по какому формату работает ККТ.

Согласно нормативно-правовым документам: Приказ ФНС России от 14.09.2020 № ЕД-7-20/662@ и п.4 статьи 4.3 54-ФЗ.

Для исправления ошибки в чеке – неправильная СНО / НДС / цена товара

  • Необходимо сформировать чек возврата абсолютно идентичный неправильному чеку прихода. В случае, если расчет был картой и невозможно сразу пробить возврат – следует оформить возврат через нефискальный приход и фискальный возврат. Способ оплаты “безналичные”.
  • Необходимо сформировать новый кассовый чек прихода с указанием правильных реквизитов. Даже если оплачивали раньше картой, необходимо пробить приход как “безналичный”.
  • Необходимо сформировать пояснительную записку с описанием ФП и ФД некорректного чека, указать причину, по которой ошибку исправляли, указать ФД и ФП нового правильного чека прихода. Эту пояснительную в любой форме передать в ФНС, либо через лк фнс, либо отнести в отделение.

В случае, если ККТ при расчете не применили – формируется чек-коррекции.

Касса не заряжается при использовании переходника aQsi Hub

  • Опустить шторку / Спец возможности,
  • Включить пункт OTG HUB & Параллельная зарядка.
  • Подключить aQsi Hub к aQsi кассе через USB Type-C.
  • Подключить патч-корд Ethernet, второй конец подключить к источнику, раздающему Ethernet (интернет-розетка, маршрутизатор и прочее).
  • Если после этого зарядка не идет, попробуйте использовать другой провод питания

Ошибка 116 : ошибка файлового ввода вывода

Данная ошибка может возникать по двум причинам:

  • Заполнена память. Необходимо очистить память на кассе, перезагрузить (reboot) и проверить работоспособность.
  • Не обновлено приложение MCU. Настройки/ Тех.обслуживание ККТ / Доп.операции / Принудительное обновление MCU. Перезагрузить кассу (reboot). Проверить работоспособность.

В случае, если ошибка сохраняется- необходимо обратиться в службу поддержки.

Ошибка 20 ФН Ограничение ресурса ФН

Ошибка говорит о том, что данные не передаются в ОФД и налоговую. Если данные не уходят в течение 30 дней – касса блокируется (ошибка 20).

  • Возможно, смена не была вовремя закрыта: Необходимо изменить время на кассе (опускаете шторку настроек Android на кассе движением пальца сверху вниз, открываете настройки – Дата и время). Установите значения даты и времени на время, когда была открыта последняя смена.Далее зайдите в настройки в главном меню – Техническое обслуживание ККТ – Дополнительные операции – Дата и время – установить системное (нажимаем на надпись системное).Закройте смену и верните корректное время по такому же алгоритму.
  • Проверьте стабильность интернета (без подключения к сети – чеки не отправляются).
  • Проверьте подключение к ОФД:
    Вам нужно на кассе зайти в Настройки / тех. обслуживание ККТ / подключение к ОФД. Далее нужно сверить настройки и исправить их, если они неверные. (https://kassopttorg.ru/questions/12732/ – список параметров)
    IP —
    Порт —
    Таймаут — 30
  • Если все установлено корректно, то нужно направить клиента в ОФД, возможно, что услуги в ОФД не оплачены.

Ошибка Notimplemented при закрытии смены

Необходимо зайти на кассе в Настройки / Основные настройки / Смены / “Перезагрузка рабочих ключей при закрытии смены” – выкл.

Ошибка QR кода маркировки в ЛК на вкладке Товароучет

Необходимо открыть раздел в ЛК – Настройки / Общее / Учёт кодов маркировки – выкл.

Ошибка 126 в чеке коррекции.

Ошибка 126 говорит о том, что поле “Номер документа основания” заполнено некорректно.

Если тип коррекции “Самостоятельно”, то номером документа является порядковый номер пояснительной (объяснительной) записки.

Ошибка 7 ФН (подходит и для ошибки 23)

Опустите шторку Андроида / Шестеренка / Дата и время / Дата и время в сети — выкл, Часовой пояс — выкл. / Проверьте время корректное или нет. Если время некорректное – исправьте.

Закройте смену (если она была открыта).

Далее зайдите в Настройки / Тех.обслуживание ККТ / Доп.операции / Дата и время —нажмите на синее поле “установить системное”.

В этом же меню нажмите «открыть смену» (при необходимости нажмите 2 раза).

Примечание! В случае, если ошибка 7 ФН сохраняется, проверяем Дату последнего ФД в информации об устройстве. Если Дата последнего ФД установлена в будущем времени, то клиент не сможет пробивать чеки, пока на кассе не наступит эта дата.

Ошибка Read time out

Зайдите в Настройки — Тех. обслуживание ККТ — Доп. операции — Отключить печать КЯ. Закройте и откройте смену.
Затем перезагрузите кассу.

Проверьте на наличие ошибки. Если ошибка сохраняется – обратитесь в поддержку Акси.

Ошибка принтера Paper Exception Error ret null

  • Войти в настройки/ техническое обслуживание ККТ/ дополнительные операции/ нажать на “Принудительное обновление MCU”.
  • После обновления MCU нажать на “Отключить печать КЯ”.

Если ошибка сохраняется – необходимо запросить обновления в технической поддержке указав наименование ошибки.

Ошибка 51 общая

  • Убедитесь, что на кассе установлена корректная СНО в разделе Настройки / Основные / Чеки / СНО по умолчанию
  • Пройдите перефискализацию повторно. Зайдите в раздел мастер фискализации, с 1 шага проверьте все данные, обратите внимание на СНО. На 2 шаге внимательно заполните поля Адрес и Место расчетов. На 4 шаге обратите внимание на поле «сведения о применении кассы», либо ничего не заполняйте, либо выберите нужный пункт. Завершите перефискализацию с причиной «изменение настроек ККТ». Email отправителя чека – заполните электронный адрес почты нужного ОФД. Пример перерегистрации по инструкции – https://aqsi.ru/support/pereregistraciya-kassyi-c-envd-na-usn/
  • Проверьте способ и предмет расчета. Зайдите в раздел База товаров, выберите одну из товарных позиций, прикоснитесь на 2 секунды — «изменить».
  • Проверьте, чтобы в поле предмет расчета у Вас был «товар» (если продаете товары) или «услуга» (если оказываете услуги).
    Также обратите внимание на способ расчета — должен быть полный расчет.
  • После выполнения пункта 1-3 зайдите в Настройки / Тех.обслуживание ККТ / Дополнительные операции / Перезагрузить кассовое ядро.
    При нажатии звукового и видимого эффекта не будет.
  • Попробуйте оформить чек из истории или выбить новый.

Примечание: При применении ОСН + ФН на 36 месяцев, оформлять на кассе можно ТОЛЬКО УСЛУГИ!

Ошибка при сохранении в ФН

Ошибка говорит о том, что чек не сохранился в ФН и не был отправлен в ОФД и ФНС.

  • Отключить фискальный накопитель, затем плотно подключить его и перезагрузить кассу (команда reboot).
  • Далее зайти в Настройки / Тех.обслуживание ККТ / Доп.операции / Перезагрузить кассовое ядро (при нажатии ничего не произойдет, видимых эффектов не будет).
  • После этого зайти в историю чеков, нажать на чек с надписью “ошибка при сохранении” и нажать снизу “оформить чек”.

Также проверьте в Настройках / Основные настройки / Чеки / СНО по умолчанию — указана ли верная система налогообложения.

Если ошибка сохраняется, необходимо найти причину или уточнить код ошибки. Действия, соответственно, будут иные.

Окно “в работе приложения кассовое ядро …” при включении кассы

Данное сообщение не является ошибкой. Это информация о том, что при запуске ККТ кассовое ядро не успело загрузиться.
Вам необходимо закрыть уведомление и войти в кассу.

Рекомендуем зайти в Настройки / Тех. обслуживание ККТ / Доп. операции / Перезагрузить кассовое ядро. (видимых эффектов не произойдет).
Далее сделать перезагрузку ККТ (Reboot).

Ошибка Parcelable encountered ClassNotFoundException reading a Serializable object (name= re.aqsi.commons.exception.ShiftAlreadyOpenException)

Ошибка при открытии смены означает, что смена уже находится в состоянии “открыта”.

Необходимо зайти в Настройки / Тех. обслуживание ККТ / Доп. операции / Закрыть смену. Затем необходимо повторно открыть смену.

Ошибка “Исчерпан ресурс КС” или ошибка 18, когда закончился ФН

Эта ошибка говорит о том, что у клиента закончился ФН и нужно его заменить.
Но у клиента могла остаться открыта смена.

  • Движением пальца сверху вниз, откройте шторку настроек системы. Далее перейдите в «Дата и время». Установите значения даты и времени, равное последнему открытию смены.
  • В главном меню перейдите в Настройки -> Техническое обслуживание ККТ -> Дополнительные операции -> Дата и время -> установите системное (нажать на «системное»).
  • Нажмите «Закрыть ФН».

Неотправленных документов в разделе Настройки / Тех. обслуживание ККТ / Информация об устройстве – должно быть 0.

Ошибка в ЛК Orange data – Fiscalization for device … not found. / cashbox fiscalized cloudly

Для того, чтобы избавиться от ошибки Вам необходимо выполнить следующее:

Настройки / Мастер фискализации / с использованием ФН — далее / на Шаге № 2 уберите галочку «разъездная торговля» , проверьте корректность остальных полей.

Дойдите до Шага № 4:

– выберите пункт перерегистрация с причиной «изменение настроек ККТ»;

– email отправителя — адрес Вашего ОФД, выбранного на шаге № 3;

– сведения о применении ККТ — для расчетов в сети «Интернет» — поставьте галочку;

– нажмите «проверка параметров» — распечатается чек;

– нажмите «зарегистрировать кассу» — распечатается чек;

– на экране нажмите «я ввел данные», затем нажмите «готово».

После этого необходимо сгенерировать токен в личном кабинете aQsi.

– в личном кабинете Акси вкладка Настройки / Интеграции / Фискализация чеков на aQsi 5 из Оранж Дата / сгенерировать токен (ключ) / скопируйте токен;

– открыть ЛК Оранж Дата / раздел Услуги / вставьте токен(ключ) / сформируйте счет без ошибки.

Эквайринговое ядро не отвечает по тайм-ауту.

Если эквайринговое ядро не отвечает по таймауту, нужно нажать внизу экрана “Попробовать еще раз”.
Это не ошибка, а сообщение о том что касса не может достучаться до банковского хоста.
Можно перезагрузить кассу и попробовать еще раз.

Ошибка “Введены некорректные данные” при фискализации

Если касса при фискализации выдает ошибку “Введены некорректные данные” необходимо:

  • Убедиться в правильности заполнения всех полей;
  • Выполнен ли вход в кассу под пользователем Администратор.

Ошибка “Некорректный РНМ” при фискализации (перефискализации).

Если касса при фискализации выдает ошибку “Введен некорректный РНМ” необходимо:

  • Проверить подключение ФН к кассе;
  • Войти в настройки/ техническое обслуживание ККТ/ и проверить, записан ли серийный номер кассы в строке ЗН ККТ.
  • Если серийный номер в информации об устройстве отсутствует, нужно войти в Настройки/ тех обслуживание/ ввод заводского номера/ ввести заводской номер кассы в строку и нажать “Записать”.
  • Убедиться в правильности заполнения поля ОГРН на шаге 1.
  • Убедиться в правильности заполнения полей “Сведения о пользователе” на шаге 2.
  • Убедиться в правильности заполнения поля Email отправителя чека – электронный адрес ОФД.
  • Если все данные введены корректно, то необходимо обратиться в техническую поддержку.

Ошибка connection refused

Данная ошибка говорит о том, что касса не подключена к сети интернет. Для устранения ошибки необходимо подключить ее к сети интернет через WI-FI либо через сим-карту.

Ошибка missingdata при оплате банковской картой

Если появилась данная ошибка, то нужно зайти в НастройкиТехническое обслуживание ККТДополнительные операцииЗагрузить конфигурацию эквайрингового ядра.
Существует два варианта:

  • появляется сообщение «Успешно», это значит, что конфигурация в кассу загружена, а ошибка возникает из-за плохого интернет соединения.
  • появляется ошибка «при загрузке конфигурации произошли ошибки, код: missingdata», в данном случае для решения проблемы вам необходимо обратиться в техническую поддержку.

Заранее уточните детали операции, ИНН организации, ЗН кассы, сумма оплаты, время, вид карты, прикладывали или вставляли чипом.

Не нажимается кнопка «Регистрация кассы», только галка «Перерегистрация» (при первичной фискализации кассы)

Данная ошибка говорит о том, что касса уже была зарегистрирована. Необходимо:

Проверить статус в ЛК / проверить История чеков /проверить смены / проверить печатается ли отчет о фискализации.
Если касса б/у – необходимо сделать полный сброс в Настройках /Тех. обслуживание ККТ / Доп. операции / Полный сброс.

В случае неуспеха – отправьте запрос в техническую поддержку на переустановку РМК.

Ошибка при оплате иностранной картой

Чтобы касса принимала карты иностранных банков, необходимо отправить дополнительный запрос в aQsi. Для этого необходимо:

  • запросить ИНН организации;
  • уточнить вид деятельности;
  • уточнить размер среднего чека для применения иностранной карты (в переводе на рубли);
  • отправить запрос в поддержку (info@aqsi.ru) на подключение лимита по приему иностранных карт, указав информацию из пункт 1-3.

Примечание: услуга для клиента бесплатная.

Касса не подключается к сети Wi-fi

Необходимо проверить возможные ограничения сети:

  • Опустить шторку Андроид / нажать и удерживать значок “батареи” / Режим энергосбережения – отключить
  • Опустить шторку Андроид / Шестеренка / Передача данных / Экономия трафика – выкл.
  • Опустить шторку Андроид / Шестеренка / Передача данных / Ограничения трафика – выкл.
  • Проверить актуальность времени в шторке / Шестеренка / Дата и время.

Ошибка «Отсутствует чековая лента», либо «Отсутствует фискальный накопитель»

При возникновении данной ошибки, необходимо:

  • Не отключая устройство, отсоединить от него фискальный накопитель и аккумулятор, в последовательности (Фискальный накопитель/Аккумулятор).
  • Подключить фискальный накопитель и аккумулятор обратно к устройству, в последовательности (Аккумулятор/Фискальный накопитель).
  • После включения аппарата ошибки не будет.

Касса печатает неверную СНО

Зайдите в “Настройки” / “Мастер фискализации”, проверьте пошагово корректность введенных данных (СНО выбирается на 1 шаге), на 4 шаге поставьте точку на «перерегистрация кассы», в причинах укажите «изменение настроек ККТ», после перефискализируйте кассу.

Примечание: Настройки мастера фискализации необходимо проводить только при закрытой смене.

После заставки aQsi касса выключается

Для того чтобы включить кассу, необходимо:

  • Подключите к кассе провод зарядки и начинайте включать аппарат, после того как аппарат начнёт включаться выньте из него аккумулятор.
  • Отключите провод зарядного устройства, вставьте аккумулятор и включите.
  • После этих действий войдите в Настройки/ техническое обслуживание ККТ/ дополнительные операции/ и нажмите «Принудительное обновление MCU”.

Ошибки 1002, 211. Ошибка печати

Для устранения данных ошибок, необходимо:

  • Войти в настройки/ техническое обслуживание ККТ/ дополнительные операции/ нажать на “Принудительное обновление MCU”.
  • После обновления MCU нажать на “Отключить печать КЯ”, ошибка уйдет.

Ошибки 115, 77 и 94 (общие) после обновления кассы

Выполните, пожалуйста, следующую инструкцию:

  • Зайдите на кассе в Настройки / тех. обслуживание ККТ / доп. операции и нажмите на «Принудительное обновление МСЮ». Закройте смену и откройте ее снова.
  • Перезагрузите кассу
  • Зайдите в Настройки / Основные настройки / Чеки и проверьте, что там указана верная система налогообложения.
  • Далее зайдите в «Историю чеков» и оформите повторно чек с ошибкой.

Ошибка 178: Код ошибки 32h(50) от ФН: Запрещена работа с маркированными товарами.

Данная ошибка возникает в момент сканирования маркированного товара при продаже, если касса не фискализирована с галочкой “при приеме маркированного товара” в Мастере фискализации.

Нужно закрыть смену и фискализировать кассу правильно.

Маркированный товар

В форматах ФФД 1.05 и 1.1, в бумажном чеке рядом с маркированным товаром ставится префикс [M]. В чеках ФФД 1.2 у префикса появились вариации:

(М+) – проверка в фискальном накопителе и системе маркировки прошли успешно. Для покупателя это значит, что он точно купил оригинальный маркированный товар.

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

(М-) хотя бы одна проверка завершилась провалом. Для покупателя это значит, что с товаром точно что-то не так.

Настройки / Основные настройки / Чеки / Режим проверки маркировки.

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

Ошибка 33h (51) от ККТ: некорректные параметры в команде при фискализации / перефискализации

При возникновении данной ошибки необходимо снять отчет о текущем состоянии расчетов.

Далее в Мастере фискализации необходимо обязательно выбрать ИНН организации из выпадающего списка, проверить правильность всех введенных данных на каждом шаге Мастера фискализации.

Примечание: Код ошибки 33h (51) от ККТ: передает причину ошибки в самом запросе. Например, код ошибки 33h (51) от ккт: некорректные параметры в команде – для устранения требуется сформировать отчет, ошибка уйдет.

Ошибка 162. Код ошибки 34h(52) от ФН: Работа с маркированными товарами временно заблокирована

Для устранения ошибки необходимо проверить и указать корректные данные для подключения к ОФД и настройки ОИСМ.

– Зайдите в раздел Настройки / Тех. обслуживание ККТ / Подключение к ОФД – Проверьте данные согласно вашему ОФД по ссылке https://kassopttorg.ru/questions/12732/

Ошибка 3005 при оплате картой.

Ошибка дубля транзакции. Необходимо запросить информацию об успешности платежа в поддержке aQsi, отправив запрос на почту info@aqsi.ru с указанием ИНН, суммы и времени платежа.

Ошибка 3004 при оплате картой.

Необходимо запросить у клиента информацию:

  • ИНН
  • Сумма и время транзакции
  • Вид карты
  • Способ оплаты (nfc / чип)

Передать информацию в aQsi для уточнения причины ошибки в Банке.

Источник

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

Ошибка входа: credentials cannot be null

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

Что делать с ошибкой null

Если у вас нет лицензионной игры, вы скорее всего играете через лаунчер по названием Tlauncher. Данный клиент, позволяет играть в Майнкрафт в последние версии абсолютно бесплатно. Разработчики ежемесячно обновляют совой клиент. После обновлений пользователь может столкнуться с ошибкой при входе на сервер. В этом случае попробуйте выполнить последовательно следующие действия:

  1. Запустите приложение Tlauncher;
  2. Авторизуйтесь в клиенте, если у вас нет аккаунта, то необходимо создать;
  3. Далее в нижем левом экране, возле «Аккаунты» уберите галочку;Снимите птичку с аккаунтов
  4. Готово, теперь вы можете попробовать зайти на какой-нибудь сервер.

Отключение антивируса

Отключите антивирус во время обновления или игры Майнкрафт. Для этого проделайте действия:

  1. Нажмите правой кнопкой мыши значок антивируса в области уведомлений;
    Нажмите на антивирус
  2. Теперь выберите приостановить антивирус;
  3. Далее выберите подходящий параметр времени для отключения антивируса (например, 10 минут, 1 час, приостановить до следующей перезагрузки).

Заключение

Из этой статьи вы узнали, как исправить проблему при соединении к серверам в Майнкрафт. Если ничего не помогло из вышеперечисленного, удалите полностью игру с вашего компьютера, и установите новую скачав с официального сайта. Остались вопросы? Напишите ниже в форме комментариев.

Оценка статьи:

Загрузка…

// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==—== /* Note on transaction support: Eventually we will want to add support for NT’s transactions to our RegistryKey API’s (possibly Whidbey M3?). When we do this, here’s the list of API’s we need to make transaction-aware: RegCreateKeyEx RegDeleteKey RegDeleteValue RegEnumKeyEx RegEnumValue RegOpenKeyEx RegQueryInfoKey RegQueryValueEx RegSetValueEx We can ignore RegConnectRegistry (remote registry access doesn’t yet have transaction support) and RegFlushKey. RegCloseKey doesn’t require any additional work. . */ /* Note on ACL support: The key thing to note about ACL’s is you set them on a kernel object like a registry key, then the ACL only gets checked when you construct handles to them. So if you set an ACL to deny read access to yourself, you’ll still be able to read with that handle, but not with new handles. Another peculiarity is a Terminal Server app compatibility hack. The OS will second guess your attempt to open a handle sometimes. If a certain combination of Terminal Server app compat registry keys are set, then the OS will try to reopen your handle with lesser permissions if you couldn’t open it in the specified mode. So on some machines, we will see handles that may not be able to read or write to a registry key. It’s very strange. But the real test of these handles is attempting to read or set a value in an affected registry key. For reference, at least two registry keys must be set to particular values for this behavior: HKLMSOFTWAREMicrosoftWindows NTCurrentVersionTerminal ServerRegistryExtensionFlags, the least significant bit must be 1. HKLMSYSTEMCurrentControlSetControlTerminalServerTSAppCompat must be 1 There might possibly be an interaction with yet a third registry key as well. */ namespace Microsoft.Win32 { using System; using System.Collections; using System.Collections.Generic; using System.Security; #if FEATURE_MACL using System.Security.AccessControl; #endif using System.Security.Permissions; using System.Text; using System.Threading; using System.IO; using System.Runtime.Remoting; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; using System.Runtime.Versioning; using System.Globalization; using System.Diagnostics.Contracts; using System.Diagnostics.CodeAnalysis; #if !FEATURE_PAL /** * Registry hive values. Useful only for GetRemoteBaseKey */ [Serializable] [System.Runtime.InteropServices.ComVisible(true)] public enum RegistryHive { ClassesRoot = unchecked((int)0x80000000), CurrentUser = unchecked((int)0x80000001), LocalMachine = unchecked((int)0x80000002), Users = unchecked((int)0x80000003), PerformanceData = unchecked((int)0x80000004), CurrentConfig = unchecked((int)0x80000005), DynData = unchecked((int)0x80000006), } /** * Registry encapsulation. To get an instance of a RegistryKey use the * Registry class’s static members then call OpenSubKey. * * @see Registry * @security(checkDllCalls=off) * @security(checkClassLinking=on) */ #if FEATURE_REMOTING [ComVisible(true)] public sealed class RegistryKey : MarshalByRefObject, IDisposable #else [ComVisible(true)] public sealed class RegistryKey : IDisposable #endif { // We could use const here, if C# supported ELEMENT_TYPE_I fully. internal static readonly IntPtr HKEY_CLASSES_ROOT = new IntPtr(unchecked((int)0x80000000)); internal static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001)); internal static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002)); internal static readonly IntPtr HKEY_USERS = new IntPtr(unchecked((int)0x80000003)); internal static readonly IntPtr HKEY_PERFORMANCE_DATA = new IntPtr(unchecked((int)0x80000004)); internal static readonly IntPtr HKEY_CURRENT_CONFIG = new IntPtr(unchecked((int)0x80000005)); internal static readonly IntPtr HKEY_DYN_DATA = new IntPtr(unchecked((int)0x80000006)); // Dirty indicates that we have munged data that should be potentially // written to disk. // private const int STATE_DIRTY = 0x0001; // SystemKey indicates that this is a «SYSTEMKEY» and shouldn’t be «opened» // or «closed». // private const int STATE_SYSTEMKEY = 0x0002; // Access // private const int STATE_WRITEACCESS = 0x0004; // Indicates if this key is for HKEY_PERFORMANCE_DATA private const int STATE_PERF_DATA = 0x0008; // Names of keys. This array must be in the same order as the HKEY values listed above. // private static readonly String[] hkeyNames = new String[] { «HKEY_CLASSES_ROOT«, «HKEY_CURRENT_USER«, «HKEY_LOCAL_MACHINE«, «HKEY_USERS«, «HKEY_PERFORMANCE_DATA«, «HKEY_CURRENT_CONFIG«, «HKEY_DYN_DATA« }; // MSDN defines the following limits for registry key names & values: // Key Name: 255 characters // Value name: 16,383 Unicode characters // Value: either 1 MB or current available memory, depending on registry format. private const int MaxKeyLength = 255; private const int MaxValueLength = 16383; [System.Security.SecurityCritical] // auto-generated private volatile SafeRegistryHandle hkey = null; private volatile int state = 0; private volatile String keyName; private volatile bool remoteKey = false; private volatile RegistryKeyPermissionCheck checkMode; private volatile RegistryView regView = RegistryView.Default; /** * RegistryInternalCheck values. Useful only for CheckPermission */ private enum RegistryInternalCheck { CheckSubKeyWritePermission = 0, CheckSubKeyReadPermission = 1, CheckSubKeyCreatePermission = 2, CheckSubTreeReadPermission = 3, CheckSubTreeWritePermission = 4, CheckSubTreeReadWritePermission = 5, CheckValueWritePermission = 6, CheckValueCreatePermission = 7, CheckValueReadPermission = 8, CheckKeyReadPermission = 9, CheckSubTreePermission = 10, CheckOpenSubKeyWithWritablePermission = 11, CheckOpenSubKeyPermission = 12 }; /** * Creates a RegistryKey. * * This key is bound to hkey, if writable is <b>false</b> then no write operations * will be allowed. */ [System.Security.SecurityCritical] // auto-generated private RegistryKey(SafeRegistryHandle hkey, bool writable, RegistryView view) : this(hkey, writable, false, false, false, view) { } /** * Creates a RegistryKey. * * This key is bound to hkey, if writable is <b>false</b> then no write operations * will be allowed. If systemkey is set then the hkey won’t be released * when the object is GC’ed. * The remoteKey flag when set to true indicates that we are dealing with registry entries * on a remote machine and requires the program making these calls to have full trust. */ [System.Security.SecurityCritical] // auto-generated private RegistryKey(SafeRegistryHandle hkey, bool writable, bool systemkey, bool remoteKey, bool isPerfData, RegistryView view) { this.hkey = hkey; this.keyName = ««; this.remoteKey = remoteKey; this.regView = view; if (systemkey) { this.state |= STATE_SYSTEMKEY; } if (writable) { this.state |= STATE_WRITEACCESS; } if (isPerfData) this.state |= STATE_PERF_DATA; ValidateKeyView(view); } /** * Closes this key, flushes it to disk if the contents have been modified. */ public void Close() { Dispose(true); } [System.Security.SecuritySafeCritical] // auto-generated private void Dispose(bool disposing) { if (hkey != null) { if (!IsSystemKey()) { try { hkey.Dispose(); } catch (IOException){ // we don’t really care if the handle is invalid at this point } finally { hkey = null; } } else if (disposing && IsPerfDataKey()) { // System keys should never be closed. However, we want to call RegCloseKey // on HKEY_PERFORMANCE_DATA when called from PerformanceCounter.CloseSharedResources // (i.e. when disposing is true) so that we release the PERFLIB cache and cause it // to be refreshed (by re-reading the registry) when accessed subsequently. // This is the only way we can see the just installed perf counter. // NOTE: since HKEY_PERFORMANCE_DATA is process wide, there is inherent —- in closing // the key asynchronously. While Vista is smart enough to rebuild the PERFLIB resources // in this situation the down level OSes are not. We have a small window of —- between // the dispose below and usage elsewhere (other threads). This is By Design. // This is less of an issue when OS > NT5 (i.e Vista & higher), we can close the perfkey // (to release & refresh PERFLIB resources) and the OS will rebuild PERFLIB as necessary. SafeRegistryHandle.RegCloseKey(RegistryKey.HKEY_PERFORMANCE_DATA); } } } [System.Security.SecuritySafeCritical] // auto-generated public void Flush() { if (hkey != null) { if (IsDirty()) { Win32Native.RegFlushKey(hkey); } } } #if FEATURE_CORECLR void IDisposable.Dispose() #else public void Dispose() #endif { Dispose(true); } /** * Creates a new subkey, or opens an existing one. * * @param subkey Name or path to subkey to create or open. * * @return the subkey, or <b>null</b> if the operation failed. */ [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [SuppressMessage(«Microsoft.Concurrency«, «CA8001«, Justification = «Reviewed for thread safety«)] public RegistryKey CreateSubKey(String subkey) { return CreateSubKey(subkey, checkMode); } [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public RegistryKey CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck) { return CreateSubKeyInternal(subkey, permissionCheck, null, RegistryOptions.None); } [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public RegistryKey CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck, RegistryOptions options) { return CreateSubKeyInternal(subkey, permissionCheck, null, options); } [ComVisible(false)] public RegistryKey CreateSubKey(String subkey, bool writable) { return CreateSubKeyInternal(subkey, writable ? RegistryKeyPermissionCheck.ReadWriteSubTree : RegistryKeyPermissionCheck.ReadSubTree, null, RegistryOptions.None); } [ComVisible(false)] public RegistryKey CreateSubKey(String subkey, bool writable, RegistryOptions options) { return CreateSubKeyInternal(subkey, writable ? RegistryKeyPermissionCheck.ReadWriteSubTree : RegistryKeyPermissionCheck.ReadSubTree, null, options); } #if FEATURE_MACL [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public unsafe RegistryKey CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck, RegistrySecurity registrySecurity) { return CreateSubKeyInternal(subkey, permissionCheck, registrySecurity, RegistryOptions.None); } [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public unsafe RegistryKey CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck, RegistryOptions registryOptions, RegistrySecurity registrySecurity) { return CreateSubKeyInternal(subkey, permissionCheck, registrySecurity, registryOptions); } #endif [System.Security.SecuritySafeCritical] // auto-generated [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private unsafe RegistryKey CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, object registrySecurityObj, RegistryOptions registryOptions) { ValidateKeyOptions(registryOptions); ValidateKeyName(subkey); ValidateKeyMode(permissionCheck); EnsureWriteable(); subkey = FixupName(subkey); // Fixup multiple slashes to a single slash // only keys opened under read mode is not writable if (!remoteKey) { RegistryKey key = InternalOpenSubKey(subkey, (permissionCheck != RegistryKeyPermissionCheck.ReadSubTree)); if (key != null) { // Key already exits CheckPermission(RegistryInternalCheck.CheckSubKeyWritePermission, subkey, false, RegistryKeyPermissionCheck.Default); CheckPermission(RegistryInternalCheck.CheckSubTreePermission, subkey, false, permissionCheck); key.checkMode = permissionCheck; return key; } } CheckPermission(RegistryInternalCheck.CheckSubKeyCreatePermission, subkey, false, RegistryKeyPermissionCheck.Default); Win32Native.SECURITY_ATTRIBUTES secAttrs = null; #if FEATURE_MACL RegistrySecurity registrySecurity = (RegistrySecurity)registrySecurityObj; // For ACL’s, get the security descriptor from the RegistrySecurity. if (registrySecurity != null) { secAttrs = new Win32Native.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = registrySecurity.GetSecurityDescriptorBinaryForm(); // We allocate memory on the stack to improve the speed. // So this part of code can’t be refactored into a method. byte* pSecDescriptor = stackalloc byte[sd.Length]; Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length); secAttrs.pSecurityDescriptor = pSecDescriptor; } #endif int disposition = 0; // By default, the new key will be writable. SafeRegistryHandle result = null; int ret = Win32Native.RegCreateKeyEx(hkey, subkey, 0, null, (int)registryOptions /* specifies if the key is volatile */, GetRegistryKeyAccess(permissionCheck != RegistryKeyPermissionCheck.ReadSubTree) | (int)regView, secAttrs, out result, out disposition); if (ret == 0 && !result.IsInvalid) { RegistryKey key = new RegistryKey(result, (permissionCheck != RegistryKeyPermissionCheck.ReadSubTree), false, remoteKey, false, regView); CheckPermission(RegistryInternalCheck.CheckSubTreePermission, subkey, false, permissionCheck); key.checkMode = permissionCheck; if (subkey.Length == 0) key.keyName = keyName; else key.keyName = keyName + «\« + subkey; return key; } else if (ret != 0) // syscall failed, ret is an error code. Win32Error(ret, keyName + «\« + subkey); // Access denied? BCLDebug.Assert(false, «Unexpected code path in RegistryKey::CreateSubKey«); return null; } /** * Deletes the specified subkey. Will throw an exception if the subkey has * subkeys. To delete a tree of subkeys use, DeleteSubKeyTree. * * @param subkey SubKey to delete. * * @exception InvalidOperationException thrown if the subkey has child subkeys. */ [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void DeleteSubKey(String subkey) { DeleteSubKey(subkey, true); } [System.Security.SecuritySafeCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void DeleteSubKey(String subkey, bool throwOnMissingSubKey) { ValidateKeyName(subkey); EnsureWriteable(); subkey = FixupName(subkey); // Fixup multiple slashes to a single slash CheckPermission(RegistryInternalCheck.CheckSubKeyWritePermission, subkey, false, RegistryKeyPermissionCheck.Default); // Open the key we are deleting and check for children. Be sure to // explicitly call close to avoid keeping an extra HKEY open. // RegistryKey key = InternalOpenSubKey(subkey,false); if (key != null) { try { if (key.InternalSubKeyCount() > 0) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_RegRemoveSubKey); } } finally { key.Close(); } int ret; try { ret = Win32Native.RegDeleteKeyEx(hkey, subkey, (int)regView, 0); } catch (EntryPointNotFoundException) { // ret = Win32Native.RegDeleteKey(hkey, subkey); } if (ret!=0) { if (ret == Win32Native.ERROR_FILE_NOT_FOUND) { if (throwOnMissingSubKey) ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyAbsent); } else Win32Error(ret, null); } } else { // there is no key which also means there is no subkey if (throwOnMissingSubKey) ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyAbsent); } } /** * Recursively deletes a subkey and any child subkeys. * * @param subkey SubKey to delete. */ [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void DeleteSubKeyTree(String subkey) { DeleteSubKeyTree(subkey, true /*throwOnMissingSubKey*/); } [System.Security.SecuritySafeCritical] // auto-generated [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void DeleteSubKeyTree(String subkey, Boolean throwOnMissingSubKey) { ValidateKeyName(subkey); // Security concern: Deleting a hive’s «» subkey would delete all // of that hive’s contents. Don’t allow «». if (subkey.Length==0 && IsSystemKey()) { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegKeyDelHive); } EnsureWriteable(); subkey = FixupName(subkey); // Fixup multiple slashes to a single slash CheckPermission(RegistryInternalCheck.CheckSubTreeWritePermission, subkey, false, RegistryKeyPermissionCheck.Default); RegistryKey key = InternalOpenSubKey(subkey, true); if (key != null) { try { if (key.InternalSubKeyCount() > 0) { String[] keys = key.InternalGetSubKeyNames(); for (int i=0; i<keys.Length; i++) { key.DeleteSubKeyTreeInternal(keys[i]); } } } finally { key.Close(); } int ret; try { ret = Win32Native.RegDeleteKeyEx(hkey, subkey, (int)regView, 0); } catch (EntryPointNotFoundException) { // ret = Win32Native.RegDeleteKey(hkey, subkey); } if (ret!=0) Win32Error(ret, null); } else if(throwOnMissingSubKey) { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyAbsent); } } // An internal version which does no security checks or argument checking. Skipping the // security checks should give us a slight perf gain on large trees. [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private void DeleteSubKeyTreeInternal(string subkey) { RegistryKey key = InternalOpenSubKey(subkey, true); if (key != null) { try { if (key.InternalSubKeyCount() > 0) { String[] keys = key.InternalGetSubKeyNames(); for (int i=0; i<keys.Length; i++) { key.DeleteSubKeyTreeInternal(keys[i]); } } } finally { key.Close(); } int ret; try { ret = Win32Native.RegDeleteKeyEx(hkey, subkey, (int)regView, 0); } catch (EntryPointNotFoundException) { // ret = Win32Native.RegDeleteKey(hkey, subkey); } if (ret!=0) Win32Error(ret, null); } else { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyAbsent); } } /** * Deletes the specified value from this key. * * @param name Name of value to delete. */ [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public void DeleteValue(String name) { DeleteValue(name, true); } [System.Security.SecuritySafeCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public void DeleteValue(String name, bool throwOnMissingValue) { EnsureWriteable(); CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default); int errorCode = Win32Native.RegDeleteValue(hkey, name); // // From windows 2003 server, if the name is too long we will get error code ERROR_FILENAME_EXCED_RANGE // This still means the name doesn’t exist. We need to be consistent with previous OS. // if (errorCode == Win32Native.ERROR_FILE_NOT_FOUND || errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE) { if (throwOnMissingValue) { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyValueAbsent); } // Otherwise, just return giving no indication to the user. // (For compatibility) } // We really should throw an exception here if errorCode was bad, // but we can’t for compatibility reasons. BCLDebug.Correctness(errorCode == 0, «RegDeleteValue failed. Here’s your error code: «+errorCode); } /** * Retrieves a new RegistryKey that represents the requested key. Valid * values are: * * HKEY_CLASSES_ROOT, * HKEY_CURRENT_USER, * HKEY_LOCAL_MACHINE, * HKEY_USERS, * HKEY_PERFORMANCE_DATA, * HKEY_CURRENT_CONFIG, * HKEY_DYN_DATA. * * @param hKey HKEY_* to open. * * @return the RegistryKey requested. */ [System.Security.SecurityCritical] // auto-generated internal static RegistryKey GetBaseKey(IntPtr hKey) { return GetBaseKey(hKey, RegistryView.Default); } [System.Security.SecurityCritical] // auto-generated internal static RegistryKey GetBaseKey(IntPtr hKey, RegistryView view) { int index = ((int)hKey) & 0x0FFFFFFF; BCLDebug.Assert(index >= 0 && index < hkeyNames.Length, «index is out of range!«); BCLDebug.Assert((((int)hKey) & 0xFFFFFFF0) == 0x80000000, «Invalid hkey value!«); bool isPerf = hKey == HKEY_PERFORMANCE_DATA; // only mark the SafeHandle as ownsHandle if the key is HKEY_PERFORMANCE_DATA. SafeRegistryHandle srh = new SafeRegistryHandle(hKey, isPerf); RegistryKey key = new RegistryKey(srh, true, true,false, isPerf, view); key.checkMode = RegistryKeyPermissionCheck.Default; key.keyName = hkeyNames[index]; return key; } [System.Security.SecuritySafeCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [ComVisible(false)] public static RegistryKey OpenBaseKey(RegistryHive hKey, RegistryView view) { ValidateKeyView(view); CheckUnmanagedCodePermission(); return GetBaseKey((IntPtr)((int)hKey), view); } /** * Retrieves a new RegistryKey that represents the requested key on a foreign * machine. Valid values for hKey are members of the RegistryHive enum, or * Win32 integers such as: * * HKEY_CLASSES_ROOT, * HKEY_CURRENT_USER, * HKEY_LOCAL_MACHINE, * HKEY_USERS, * HKEY_PERFORMANCE_DATA, * HKEY_CURRENT_CONFIG, * HKEY_DYN_DATA. * * @param hKey HKEY_* to open. * @param machineName the machine to connect to * * @return the RegistryKey requested. */ [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static RegistryKey OpenRemoteBaseKey(RegistryHive hKey, String machineName) { return OpenRemoteBaseKey(hKey, machineName, RegistryView.Default); } [System.Security.SecuritySafeCritical] // auto-generated [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static RegistryKey OpenRemoteBaseKey(RegistryHive hKey, String machineName, RegistryView view) { if (machineName==null) throw new ArgumentNullException(«machineName«); int index = (int)hKey & 0x0FFFFFFF; if (index < 0 || index >= hkeyNames.Length || ((int)hKey & 0xFFFFFFF0) != 0x80000000) { throw new ArgumentException(Environment.GetResourceString(«Arg_RegKeyOutOfRange«)); } ValidateKeyView(view); CheckUnmanagedCodePermission(); // connect to the specified remote registry SafeRegistryHandle foreignHKey = null; int ret = Win32Native.RegConnectRegistry(machineName, new SafeRegistryHandle(new IntPtr((int)hKey), false), out foreignHKey); if (ret == Win32Native.ERROR_DLL_INIT_FAILED) // return value indicates an error occurred throw new ArgumentException(Environment.GetResourceString(«Arg_DllInitFailure«)); if (ret != 0) Win32ErrorStatic(ret, null); if (foreignHKey.IsInvalid) // return value indicates an error occurred throw new ArgumentException(Environment.GetResourceString(«Arg_RegKeyNoRemoteConnect«, machineName)); RegistryKey key = new RegistryKey(foreignHKey, true, false, true, ((IntPtr) hKey) == HKEY_PERFORMANCE_DATA, view); key.checkMode = RegistryKeyPermissionCheck.Default; key.keyName = hkeyNames[index]; return key; } /** * Retrieves a subkey. If readonly is <b>true</b>, then the subkey is opened with * read-only access. * * @param name Name or path of subkey to open. * @param readonly Set to <b>true</b> if you only need readonly access. * * @return the Subkey requested, or <b>null</b> if the operation failed. */ #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #else [System.Security.SecuritySafeCritical] #endif [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public RegistryKey OpenSubKey(string name, bool writable ) { ValidateKeyName(name); EnsureNotDisposed(); name = FixupName(name); // Fixup multiple slashes to a single slash CheckPermission(RegistryInternalCheck.CheckOpenSubKeyWithWritablePermission, name, writable, RegistryKeyPermissionCheck.Default); SafeRegistryHandle result = null; int ret = Win32Native.RegOpenKeyEx(hkey, name, 0, GetRegistryKeyAccess(writable) | (int)regView, out result); if (ret == 0 && !result.IsInvalid) { RegistryKey key = new RegistryKey(result, writable, false, remoteKey, false, regView); key.checkMode = GetSubKeyPermissonCheck(writable); key.keyName = keyName + «\« + name; return key; } // Return null if we didn’t find the key. if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL) { // We need to throw SecurityException here for compatibility reasons, // although UnauthorizedAccessException will make more sense. ThrowHelper.ThrowSecurityException(ExceptionResource.Security_RegistryPermission); } return null; } #if FEATURE_MACL [System.Security.SecuritySafeCritical] // auto-generated [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public RegistryKey OpenSubKey(String name, RegistryKeyPermissionCheck permissionCheck) { ValidateKeyMode(permissionCheck); return InternalOpenSubKey(name, permissionCheck, GetRegistryKeyAccess(permissionCheck)); } [System.Security.SecuritySafeCritical] [ComVisible(false)] public RegistryKey OpenSubKey(String name, RegistryRights rights) { return InternalOpenSubKey(name, this.checkMode, (int)rights); } [System.Security.SecuritySafeCritical] // auto-generated [ComVisible(false)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public RegistryKey OpenSubKey(String name, RegistryKeyPermissionCheck permissionCheck, RegistryRights rights) { return InternalOpenSubKey(name, permissionCheck, (int)rights); } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private RegistryKey InternalOpenSubKey(String name, RegistryKeyPermissionCheck permissionCheck, int rights) { ValidateKeyName(name); ValidateKeyMode(permissionCheck); ValidateKeyRights(rights); EnsureNotDisposed(); name = FixupName(name); // Fixup multiple slashes to a single slash CheckPermission(RegistryInternalCheck.CheckOpenSubKeyPermission, name, false, permissionCheck); CheckPermission(RegistryInternalCheck.CheckSubTreePermission, name, false, permissionCheck); SafeRegistryHandle result = null; int ret = Win32Native.RegOpenKeyEx(hkey, name, 0, (rights | (int)regView), out result); if (ret == 0 && !result.IsInvalid) { RegistryKey key = new RegistryKey(result, (permissionCheck == RegistryKeyPermissionCheck.ReadWriteSubTree), false, remoteKey, false, regView); key.keyName = keyName + «\« + name; key.checkMode = permissionCheck; return key; } // Return null if we didn’t find the key. if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL) { // We need to throw SecurityException here for compatiblity reason, // although UnauthorizedAccessException will make more sense. ThrowHelper.ThrowSecurityException(ExceptionResource.Security_RegistryPermission); } return null; } #endif // This required no security checks. This is to get around the Deleting SubKeys which only require // write permission. They call OpenSubKey which required read. Now instead call this function w/o security checks [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] internal RegistryKey InternalOpenSubKey(String name, bool writable) { ValidateKeyName(name); EnsureNotDisposed(); SafeRegistryHandle result = null; int ret = Win32Native.RegOpenKeyEx(hkey, name, 0, GetRegistryKeyAccess(writable) | (int)regView, out result); if (ret == 0 && !result.IsInvalid) { RegistryKey key = new RegistryKey(result, writable, false, remoteKey, false, regView); key.keyName = keyName + «\« + name; return key; } return null; } /** * Returns a subkey with read only permissions. * * @param name Name or path of subkey to open. * * @return the Subkey requested, or <b>null</b> if the operation failed. */ [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] #if FEATURE_CORECLR [System.Security.SecurityCritical] #endif public RegistryKey OpenSubKey(String name) { return OpenSubKey(name, false); } /** * Retrieves the count of subkeys. * * @return a count of subkeys. */ public int SubKeyCount { [System.Security.SecuritySafeCritical] // auto-generated get { CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default); return InternalSubKeyCount(); } } [ComVisible(false)] public RegistryView View { [System.Security.SecuritySafeCritical] get { EnsureNotDisposed(); return regView; } } #if !FEATURE_CORECLR [ComVisible(false)] public SafeRegistryHandle Handle { [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [System.Security.SecurityCritical] [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { EnsureNotDisposed(); int ret = Win32Native.ERROR_INVALID_HANDLE; if (IsSystemKey()) { IntPtr baseKey = (IntPtr)0; switch (keyName) { case «HKEY_CLASSES_ROOT«: baseKey = HKEY_CLASSES_ROOT; break; case «HKEY_CURRENT_USER«: baseKey = HKEY_CURRENT_USER; break; case «HKEY_LOCAL_MACHINE«: baseKey = HKEY_LOCAL_MACHINE; break; case «HKEY_USERS«: baseKey = HKEY_USERS; break; case «HKEY_PERFORMANCE_DATA«: baseKey = HKEY_PERFORMANCE_DATA; break; case «HKEY_CURRENT_CONFIG«: baseKey = HKEY_CURRENT_CONFIG; break; case «HKEY_DYN_DATA«: baseKey = HKEY_DYN_DATA; break; default: Win32Error(ret, null); break; } // open the base key so that RegistryKey.Handle will return a valid handle SafeRegistryHandle result; ret = Win32Native.RegOpenKeyEx(baseKey, null, 0, GetRegistryKeyAccess(IsWritable()) | (int)regView, out result); if (ret == 0 && !result.IsInvalid) { return result; } else { Win32Error(ret, null); } } else { return hkey; } throw new IOException(Win32Native.GetMessage(ret), ret); } } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [System.Security.SecurityCritical] [ComVisible(false)] [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static RegistryKey FromHandle(SafeRegistryHandle handle) { return FromHandle(handle, RegistryView.Default); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [System.Security.SecurityCritical] [ComVisible(false)] [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static RegistryKey FromHandle(SafeRegistryHandle handle, RegistryView view) { if (handle == null) throw new ArgumentNullException(«handle«); ValidateKeyView(view); return new RegistryKey(handle, true /* isWritable */, view); } #endif [System.Security.SecurityCritical] // auto-generated internal int InternalSubKeyCount() { EnsureNotDisposed(); int subkeys = 0; int junk = 0; int ret = Win32Native.RegQueryInfoKey(hkey, null, null, IntPtr.Zero, ref subkeys, // subkeys null, null, ref junk, // values null, null, null, null); if (ret != 0) Win32Error(ret, null); return subkeys; } /** * Retrieves an array of strings containing all the subkey names. * * @return all subkey names. */ #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #else [System.Security.SecuritySafeCritical] #endif public String[] GetSubKeyNames() { CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default); return InternalGetSubKeyNames(); } [System.Security.SecurityCritical] // auto-generated internal unsafe String[] InternalGetSubKeyNames() { EnsureNotDisposed(); int subkeys = InternalSubKeyCount(); String[] names = new String[subkeys]; // Returns 0-length array if empty. if (subkeys > 0) { char[] name = new char[MaxKeyLength + 1]; int namelen; fixed (char *namePtr = &name[0]) { for (int i=0; i<subkeys; i++) { namelen = name.Length; // Don’t remove this. The API’s doesn’t work if this is not properly initialised. int ret = Win32Native.RegEnumKeyEx(hkey, i, namePtr, ref namelen, null, null, null, null); if (ret != 0) Win32Error(ret, null); names[i] = new String(namePtr); } } } return names; } /** * Retrieves the count of values. * * @return a count of values. */ public int ValueCount { [System.Security.SecuritySafeCritical] // auto-generated get { CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default); return InternalValueCount(); } } [System.Security.SecurityCritical] // auto-generated internal int InternalValueCount() { EnsureNotDisposed(); int values = 0; int junk = 0; int ret = Win32Native.RegQueryInfoKey(hkey, null, null, IntPtr.Zero, ref junk, // subkeys null, null, ref values, // values null, null, null, null); if (ret != 0) Win32Error(ret, null); return values; } /** * Retrieves an array of strings containing all the value names. * * @return all value names. */ [System.Security.SecuritySafeCritical] // auto-generated public unsafe String[] GetValueNames() { CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default); EnsureNotDisposed(); int values = InternalValueCount(); String[] names = new String[values]; if (values > 0) { char[] name = new char[MaxValueLength + 1]; int namelen; fixed (char *namePtr = &name[0]) { for (int i=0; i<values; i++) { namelen = name.Length; int ret = Win32Native.RegEnumValue(hkey, i, namePtr, ref namelen, IntPtr.Zero, null, null, null); if (ret != 0) { // ignore ERROR_MORE_DATA if we’re querying HKEY_PERFORMANCE_DATA if (!(IsPerfDataKey() && ret == Win32Native.ERROR_MORE_DATA)) Win32Error(ret, null); } names[i] = new String(namePtr); } } } return names; } /** * Retrieves the specified value. <b>null</b> is returned if the value * doesn’t exist. * * Note that <var>name</var> can be null or «», at which point the * unnamed or default value of this Registry key is returned, if any. * * @param name Name of value to retrieve. * * @return the data associated with the value. */ [System.Security.SecuritySafeCritical] // auto-generated public Object GetValue(String name) { CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default); return InternalGetValue(name, null, false, true); } /** * Retrieves the specified value. <i>defaultValue</i> is returned if the value doesn’t exist. * * Note that <var>name</var> can be null or «», at which point the * unnamed or default value of this Registry key is returned, if any. * The default values for RegistryKeys are OS-dependent. NT doesn’t * have them by default, but they can exist and be of any type. On * Win95, the default value is always an empty key of type REG_SZ. * Win98 supports default values of any type, but defaults to REG_SZ. * * @param name Name of value to retrieve. * @param defaultValue Value to return if <i>name</i> doesn’t exist. * * @return the data associated with the value. */ #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #else [System.Security.SecuritySafeCritical] #endif public Object GetValue(String name, Object defaultValue) { CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default); return InternalGetValue(name, defaultValue, false, true); } #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #else [System.Security.SecuritySafeCritical] #endif [ComVisible(false)] public Object GetValue(String name, Object defaultValue, RegistryValueOptions options) { if( options < RegistryValueOptions.None || options > RegistryValueOptions.DoNotExpandEnvironmentNames) { throw new ArgumentException(Environment.GetResourceString(«Arg_EnumIllegalVal«, (int)options), «options«); } bool doNotExpand = (options == RegistryValueOptions.DoNotExpandEnvironmentNames); CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default); return InternalGetValue(name, defaultValue, doNotExpand, true); } [System.Security.SecurityCritical] // auto-generated internal Object InternalGetValue(String name, Object defaultValue, bool doNotExpand, bool checkSecurity) { if (checkSecurity) { // Name can be null! It’s the most common use of RegQueryValueEx EnsureNotDisposed(); } Object data = defaultValue; int type = 0; int datasize = 0; int ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize); if (ret != 0) { if (IsPerfDataKey()) { int size = 65000; int sizeInput = size; int r; byte[] blob = new byte[size]; while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput))) { if (size == Int32.MaxValue) { // ERROR_MORE_DATA was returned however we cannot increase the buffer size beyond Int32.MaxValue Win32Error(r, name); } else if (size > (Int32.MaxValue / 2)) { // at this point in the loop «size * 2» would cause an overflow size = Int32.MaxValue; } else { size *= 2; } sizeInput = size; blob = new byte[size]; } if (r != 0) Win32Error(r, name); return blob; } else { // For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data). // Some OS’s returned ERROR_MORE_DATA even in success cases, so we // want to continue on through the function. if (ret != Win32Native.ERROR_MORE_DATA) return data; } } if (datasize < 0) { // unexpected code path BCLDebug.Assert(false, «[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize«); datasize = 0; } switch (type) { case Win32Native.REG_NONE: case Win32Native.REG_DWORD_BIG_ENDIAN: case Win32Native.REG_BINARY: { byte[] blob = new byte[datasize]; ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); data = blob; } break; case Win32Native.REG_QWORD: { // also REG_QWORD_LITTLE_ENDIAN if (datasize > 8) { // prevent an AV in the edge case that datasize is larger than sizeof(long) goto case Win32Native.REG_BINARY; } long blob = 0; BCLDebug.Assert(datasize==8, «datasize==8«); // Here, datasize must be 8 when calling this ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize); data = blob; } break; case Win32Native.REG_DWORD: { // also REG_DWORD_LITTLE_ENDIAN if (datasize > 4) { // prevent an AV in the edge case that datasize is larger than sizeof(int) goto case Win32Native.REG_QWORD; } int blob = 0; BCLDebug.Assert(datasize==4, «datasize==4«); // Here, datasize must be four when calling this ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize); data = blob; } break; case Win32Native.REG_SZ: { if (datasize % 2 == 1) { // handle the case where the registry contains an odd-byte length (corrupt data?) try { datasize = checked(datasize + 1); } catch (OverflowException e) { throw new IOException(Environment.GetResourceString(«Arg_RegGetOverflowBug«), e); } } char[] blob = new char[datasize/2]; ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); if (blob.Length > 0 && blob[blob.Length 1] == (char)0) { data = new String(blob, 0, blob.Length 1); } else { // in the very unlikely case the data is missing null termination, // pass in the whole char[] to prevent truncating a character data = new String(blob); } } break; case Win32Native.REG_EXPAND_SZ: { if (datasize % 2 == 1) { // handle the case where the registry contains an odd-byte length (corrupt data?) try { datasize = checked(datasize + 1); } catch (OverflowException e) { throw new IOException(Environment.GetResourceString(«Arg_RegGetOverflowBug«), e); } } char[] blob = new char[datasize/2]; ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); if (blob.Length > 0 && blob[blob.Length 1] == (char)0) { data = new String(blob, 0, blob.Length 1); } else { // in the very unlikely case the data is missing null termination, // pass in the whole char[] to prevent truncating a character data = new String(blob); } if (!doNotExpand) data = Environment.ExpandEnvironmentVariables((String)data); } break; case Win32Native.REG_MULTI_SZ: { if (datasize % 2 == 1) { // handle the case where the registry contains an odd-byte length (corrupt data?) try { datasize = checked(datasize + 1); } catch (OverflowException e) { throw new IOException(Environment.GetResourceString(«Arg_RegGetOverflowBug«), e); } } char[] blob = new char[datasize/2]; ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); // make sure the string is null terminated before processing the data if (blob.Length > 0 && blob[blob.Length 1] != (char)0) { try { char[] newBlob = new char[checked(blob.Length + 1)]; for (int i = 0; i < blob.Length; i++) { newBlob[i] = blob[i]; } newBlob[newBlob.Length 1] = (char)0; blob = newBlob; } catch (OverflowException e) { throw new IOException(Environment.GetResourceString(«Arg_RegGetOverflowBug«), e); } blob[blob.Length 1] = (char)0; } IList<String> strings = new List<String>(); int cur = 0; int len = blob.Length; while (ret == 0 && cur < len) { int nextNull = cur; while (nextNull < len && blob[nextNull] != (char)0) { nextNull++; } if (nextNull < len) { BCLDebug.Assert(blob[nextNull] == (char)0, «blob[nextNull] should be 0«); if (nextNullcur > 0) { strings.Add(new String(blob, cur, nextNullcur)); } else { // we found an empty string. But if we’re at the end of the data, // it’s just the extra null terminator. if (nextNull != len1) strings.Add(String.Empty); } } else { strings.Add(new String(blob, cur, lencur)); } cur = nextNull+1; } data = new String[strings.Count]; strings.CopyTo((String[])data, 0); } break; case Win32Native.REG_LINK: default: break; } return data; } [System.Security.SecuritySafeCritical] // auto-generated [ComVisible(false)] public RegistryValueKind GetValueKind(string name) { CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default); EnsureNotDisposed(); int type = 0; int datasize = 0; int ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize); if (ret != 0) Win32Error(ret, null); if (type == Win32Native.REG_NONE) return RegistryValueKind.None; else if (!Enum.IsDefined(typeof(RegistryValueKind), type)) return RegistryValueKind.Unknown; else return (RegistryValueKind) type; } /** * Retrieves the current state of the dirty property. * * A key is marked as dirty if any operation has occured that modifies the * contents of the key. * * @return <b>true</b> if the key has been modified. */ private bool IsDirty() { return (this.state & STATE_DIRTY) != 0; } private bool IsSystemKey() { return (this.state & STATE_SYSTEMKEY) != 0; } private bool IsWritable() { return (this.state & STATE_WRITEACCESS) != 0; } private bool IsPerfDataKey() { return (this.state & STATE_PERF_DATA) != 0; } public String Name { [System.Security.SecuritySafeCritical] // auto-generated get { EnsureNotDisposed(); return keyName; } } private void SetDirty() { this.state |= STATE_DIRTY; } /** * Sets the specified value. * * @param name Name of value to store data in. * @param value Data to store. */ public void SetValue(String name, Object value) { SetValue(name, value, RegistryValueKind.Unknown); } [System.Security.SecuritySafeCritical] //auto-generated [ComVisible(false)] public unsafe void SetValue(String name, Object value, RegistryValueKind valueKind) { if (value==null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); if (name != null && name.Length > MaxValueLength) { throw new ArgumentException(Environment.GetResourceString(«Arg_RegValStrLenBug«)); } if (!Enum.IsDefined(typeof(RegistryValueKind), valueKind)) throw new ArgumentException(Environment.GetResourceString(«Arg_RegBadKeyKind«), «valueKind«); EnsureWriteable(); if (!remoteKey && ContainsRegistryValue(name)) { // Existing key CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default); } else { // Creating a new value CheckPermission(RegistryInternalCheck.CheckValueCreatePermission, name, false, RegistryKeyPermissionCheck.Default); } if (valueKind == RegistryValueKind.Unknown) { // this is to maintain compatibility with the old way of autodetecting the type. // SetValue(string, object) will come through this codepath. valueKind = CalculateValueKind(value); } int ret = 0; try { switch (valueKind) { case RegistryValueKind.ExpandString: case RegistryValueKind.String: { String data = value.ToString(); ret = Win32Native.RegSetValueEx(hkey, name, 0, valueKind, data, checked(data.Length * 2 + 2)); break; } case RegistryValueKind.MultiString: { // Other thread might modify the input array after we calculate the buffer length. // Make a copy of the input array to be safe. string[] dataStrings = (string[])(((string[])value).Clone()); int sizeInBytes = 0; // First determine the size of the array // for (int i=0; i<dataStrings.Length; i++) { if (dataStrings[i] == null) { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetStrArrNull); } sizeInBytes = checked(sizeInBytes + (dataStrings[i].Length+1) * 2); } sizeInBytes = checked(sizeInBytes + 2); byte[] basePtr = new byte[sizeInBytes]; fixed(byte* b = basePtr) { IntPtr currentPtr = new IntPtr( (void *) b); // Write out the strings… // for (int i=0; i<dataStrings.Length; i++) { // Assumes that the Strings are always null terminated. String.InternalCopy(dataStrings[i],currentPtr,(checked(dataStrings[i].Length*2))); currentPtr = new IntPtr((long)currentPtr + (checked(dataStrings[i].Length*2))); *(char*)(currentPtr.ToPointer()) = ; currentPtr = new IntPtr((long)currentPtr + 2); } *(char*)(currentPtr.ToPointer()) = ; currentPtr = new IntPtr((long)currentPtr + 2); ret = Win32Native.RegSetValueEx(hkey, name, 0, RegistryValueKind.MultiString, basePtr, sizeInBytes); } break; } case RegistryValueKind.None: case RegistryValueKind.Binary: byte[] dataBytes = (byte[]) value; ret = Win32Native.RegSetValueEx(hkey, name, 0, (valueKind == RegistryValueKind.None ? Win32Native.REG_NONE: RegistryValueKind.Binary), dataBytes, dataBytes.Length); break; case RegistryValueKind.DWord: { // We need to use Convert here because we could have a boxed type cannot be // unboxed and cast at the same time. I.e. ((int)(object)(short) 5) will fail. int data = Convert.ToInt32(value, System.Globalization.CultureInfo.InvariantCulture); ret = Win32Native.RegSetValueEx(hkey, name, 0, RegistryValueKind.DWord, ref data, 4); break; } case RegistryValueKind.QWord: { long data = Convert.ToInt64(value, System.Globalization.CultureInfo.InvariantCulture); ret = Win32Native.RegSetValueEx(hkey, name, 0, RegistryValueKind.QWord, ref data, 8); break; } } } catch (OverflowException) { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind); } catch (InvalidOperationException) { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind); } catch (FormatException) { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind); } catch (InvalidCastException) { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind); } if (ret == 0) { SetDirty(); } else Win32Error(ret, null); } private RegistryValueKind CalculateValueKind(Object value) { // This logic matches what used to be in SetValue(string name, object value) in the v1.0 and v1.1 days. // Even though we could add detection for an int64 in here, we want to maintain compatibility with the // old behavior. if (value is Int32) return RegistryValueKind.DWord; else if (value is Array) { if (value is byte[]) return RegistryValueKind.Binary; else if (value is String[]) return RegistryValueKind.MultiString; else throw new ArgumentException(Environment.GetResourceString(«Arg_RegSetBadArrType«, value.GetType().Name)); } else return RegistryValueKind.String; } /** * Retrieves a string representation of this key. * * @return a string representing the key. */ [System.Security.SecuritySafeCritical] // auto-generated public override String ToString() { EnsureNotDisposed(); return keyName; } #if FEATURE_MACL public RegistrySecurity GetAccessControl() { return GetAccessControl(AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group); } [System.Security.SecuritySafeCritical] // auto-generated public RegistrySecurity GetAccessControl(AccessControlSections includeSections) { EnsureNotDisposed(); return new RegistrySecurity(hkey, keyName, includeSections); } [System.Security.SecuritySafeCritical] // auto-generated public void SetAccessControl(RegistrySecurity registrySecurity) { EnsureWriteable(); if (registrySecurity == null) throw new ArgumentNullException(«registrySecurity«); registrySecurity.Persist(hkey, keyName); } #endif /** * After calling GetLastWin32Error(), it clears the last error field, * so you must save the HResult and pass it to this method. This method * will determine the appropriate exception to throw dependent on your * error, and depending on the error, insert a string into the message * gotten from the ResourceManager. */ [System.Security.SecuritySafeCritical] // auto-generated internal void Win32Error(int errorCode, String str) { switch (errorCode) { case Win32Native.ERROR_ACCESS_DENIED: if (str != null) throw new UnauthorizedAccessException(Environment.GetResourceString(«UnauthorizedAccess_RegistryKeyGeneric_Key«, str)); else throw new UnauthorizedAccessException(); case Win32Native.ERROR_INVALID_HANDLE: /** * For normal RegistryKey instances we dispose the SafeRegHandle and throw IOException. * However, for HKEY_PERFORMANCE_DATA (on a local or remote machine) we avoid disposing the * SafeRegHandle and only throw the IOException. This is to workaround reentrancy issues * in PerformanceCounter.NextValue() where the API could throw {NullReference, ObjectDisposed, ArgumentNull}Exception * on reentrant calls because of this error code path in RegistryKey * * Normally we’d make our caller synchronize access to a shared RegistryKey instead of doing something like this, * however we shipped PerformanceCounter.NextValue() un-synchronized in v2.0RTM and customers have taken a dependency on * this behavior (being able to simultaneously query multiple remote-machine counters on multiple threads, instead of * having serialized access). * * */ if (!IsPerfDataKey()) { this.hkey.SetHandleAsInvalid(); this.hkey = null; } goto default; case Win32Native.ERROR_FILE_NOT_FOUND: throw new IOException(Environment.GetResourceString(«Arg_RegKeyNotFound«), errorCode); default: throw new IOException(Win32Native.GetMessage(errorCode), errorCode); } } [SecuritySafeCritical] internal static void Win32ErrorStatic(int errorCode, String str) { switch (errorCode) { case Win32Native.ERROR_ACCESS_DENIED: if (str != null) throw new UnauthorizedAccessException(Environment.GetResourceString(«UnauthorizedAccess_RegistryKeyGeneric_Key«, str)); else throw new UnauthorizedAccessException(); default: throw new IOException(Win32Native.GetMessage(errorCode), errorCode); } } internal static String FixupName(String name) { BCLDebug.Assert(name!=null,«[FixupName]name!=null«); if (name.IndexOf(\) == 1) return name; StringBuilder sb = new StringBuilder(name); FixupPath(sb); int temp = sb.Length 1; if (temp >= 0 && sb[temp] == \) // Remove trailing slash sb.Length = temp; return sb.ToString(); } private static void FixupPath(StringBuilder path) { Contract.Requires(path != null); int length = path.Length; bool fixup = false; char markerChar = (char)0xFFFF; int i = 1; while (i < length 1) { if (path[i] == \) { i++; while (i < length) { if (path[i] == \) { path[i] = markerChar; i++; fixup = true; } else break; } } i++; } if (fixup) { i = 0; int j = 0; while (i < length) { if(path[i] == markerChar) { i++; continue; } path[j] = path[i]; i++; j++; } path.Length += j i; } } // // Read/Write/Create SubKey Permission // private void GetSubKeyReadPermission(string subkeyName, out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Read; path = keyName + «\« + subkeyName + «\.«; } private void GetSubKeyWritePermission(string subkeyName, out RegistryPermissionAccess access, out string path) { // If we want to open a subkey of a read-only key as writeable, we need to do the check. access = RegistryPermissionAccess.Write; path = keyName + «\« + subkeyName + «\.«; } private void GetSubKeyCreatePermission(string subkeyName, out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Create; path = keyName + «\« + subkeyName + «\.«; } // // Read/Write/ReadWrite SubTree Permission // private void GetSubTreeReadPermission(string subkeyName, out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Read; path = keyName + «\« + subkeyName + «\«; } private void GetSubTreeWritePermission(string subkeyName, out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Write; path = keyName + «\« + subkeyName + «\«; } private void GetSubTreeReadWritePermission(string subkeyName, out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Write | RegistryPermissionAccess.Read; path = keyName + «\« + subkeyName; } // // Read/Write/Create Value Permission // private void GetValueReadPermission(string valueName, out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Read; path = keyName+«\«+valueName; } private void GetValueWritePermission(string valueName, out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Write; path = keyName+«\«+valueName; } private void GetValueCreatePermission(string valueName, out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Create; path = keyName+«\«+valueName; } // Read Key Permission private void GetKeyReadPermission(out RegistryPermissionAccess access, out string path) { access = RegistryPermissionAccess.Read; path = keyName + «\.«; } [System.Security.SecurityCritical] // auto-generated private void CheckPermission(RegistryInternalCheck check, string item, bool subKeyWritable, RegistryKeyPermissionCheck subKeyCheck) { bool demand = false; RegistryPermissionAccess access = RegistryPermissionAccess.NoAccess; string path = null; #if !FEATURE_CORECLR if (CodeAccessSecurityEngine.QuickCheckForAllDemands()) { return; // full trust fast path } #endif // !FEATURE_CORECLR switch (check) { // // Read/Write/Create SubKey Permission // case RegistryInternalCheck.CheckSubKeyReadPermission: if (remoteKey) { CheckUnmanagedCodePermission(); } else { BCLDebug.Assert(checkMode == RegistryKeyPermissionCheck.Default, «Should be called from a key opened under default mode only!«); BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); demand = true; GetSubKeyReadPermission(item, out access, out path); } break; case RegistryInternalCheck.CheckSubKeyWritePermission: if (remoteKey) { CheckUnmanagedCodePermission(); } else { BCLDebug.Assert(checkMode != RegistryKeyPermissionCheck.ReadSubTree, «We shouldn’t allow creating sub key under read-only key!«); BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); if( checkMode == RegistryKeyPermissionCheck.Default) { demand = true; GetSubKeyWritePermission(item, out access, out path); } } break; case RegistryInternalCheck.CheckSubKeyCreatePermission: if (remoteKey) { CheckUnmanagedCodePermission(); } else { BCLDebug.Assert(checkMode != RegistryKeyPermissionCheck.ReadSubTree, «We shouldn’t allow creating sub key under read-only key!«); BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); if( checkMode == RegistryKeyPermissionCheck.Default) { demand = true; GetSubKeyCreatePermission(item, out access, out path); } } break; // // Read/Write/ReadWrite SubTree Permission // case RegistryInternalCheck.CheckSubTreeReadPermission: if (remoteKey) { CheckUnmanagedCodePermission(); } else { BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); if( checkMode == RegistryKeyPermissionCheck.Default) { demand = true; GetSubTreeReadPermission(item, out access, out path); } } break; case RegistryInternalCheck.CheckSubTreeWritePermission: if (remoteKey) { CheckUnmanagedCodePermission(); } else { BCLDebug.Assert(checkMode != RegistryKeyPermissionCheck.ReadSubTree, «We shouldn’t allow writing value to read-only key!«); BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); if( checkMode == RegistryKeyPermissionCheck.Default) { demand = true; GetSubTreeWritePermission(item, out access, out path); } } break; case RegistryInternalCheck.CheckSubTreeReadWritePermission: if (remoteKey) { CheckUnmanagedCodePermission(); } else { BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); // If we want to open a subkey of a read-only key as writeable, we need to do the check. demand = true; GetSubTreeReadWritePermission(item, out access, out path); } break; // // Read/Write/Create Value Permission // case RegistryInternalCheck.CheckValueReadPermission: ///*** no remoteKey check ***/// BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); if( checkMode == RegistryKeyPermissionCheck.Default) { // only need to check for default mode (dynamice check) demand = true; GetValueReadPermission(item, out access, out path); } break; case RegistryInternalCheck.CheckValueWritePermission: if (remoteKey) { CheckUnmanagedCodePermission(); } else { BCLDebug.Assert(checkMode != RegistryKeyPermissionCheck.ReadSubTree, «We shouldn’t allow writing value to read-only key!«); BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); // skip the security check if the key is opened under write mode if( checkMode == RegistryKeyPermissionCheck.Default) { demand = true; GetValueWritePermission(item, out access, out path); } } break; case RegistryInternalCheck.CheckValueCreatePermission: if (remoteKey) { CheckUnmanagedCodePermission(); } else { BCLDebug.Assert(checkMode != RegistryKeyPermissionCheck.ReadSubTree, «We shouldn’t allow creating value under read-only key!«); BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); // skip the security check if the key is opened under write mode if( checkMode == RegistryKeyPermissionCheck.Default) { demand = true; GetValueCreatePermission(item, out access, out path); } } break; // // CheckKeyReadPermission // case RegistryInternalCheck.CheckKeyReadPermission: ///*** no remoteKey check ***/// if( checkMode == RegistryKeyPermissionCheck.Default) { BCLDebug.Assert(item == null, «CheckKeyReadPermission should never have a non-null item parameter!«); BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); // only need to check for default mode (dynamice check) demand = true; GetKeyReadPermission(out access, out path); } break; // // CheckSubTreePermission // case RegistryInternalCheck.CheckSubTreePermission: BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); if( subKeyCheck == RegistryKeyPermissionCheck.ReadSubTree) { if( checkMode == RegistryKeyPermissionCheck.Default) { if( remoteKey) { CheckUnmanagedCodePermission(); } else { demand = true; GetSubTreeReadPermission(item, out access, out path); } } } else if(subKeyCheck == RegistryKeyPermissionCheck.ReadWriteSubTree) { if( checkMode != RegistryKeyPermissionCheck.ReadWriteSubTree) { if( remoteKey) { CheckUnmanagedCodePermission(); } else { demand = true; GetSubTreeReadWritePermission(item, out access, out path); } } } break; // // CheckOpenSubKeyWithWritablePermission uses the ‘subKeyWritable’ parameter // case RegistryInternalCheck.CheckOpenSubKeyWithWritablePermission: BCLDebug.Assert(subKeyCheck == RegistryKeyPermissionCheck.Default, «subKeyCheck should be Default (unused)«); // If the parent key is not opened under default mode, we have access already. // If the parent key is opened under default mode, we need to check for permission. if(checkMode == RegistryKeyPermissionCheck.Default) { if( remoteKey) { CheckUnmanagedCodePermission(); } else { demand = true; GetSubKeyReadPermission(item, out access, out path); } break; } if( subKeyWritable && (checkMode == RegistryKeyPermissionCheck.ReadSubTree)) { if( remoteKey) { CheckUnmanagedCodePermission(); } else { demand = true; GetSubTreeReadWritePermission(item, out access, out path); } break; } break; // // CheckOpenSubKeyPermission uses the ‘subKeyCheck’ parameter // case RegistryInternalCheck.CheckOpenSubKeyPermission: BCLDebug.Assert(subKeyWritable == false, «subKeyWritable should be false (unused)«); if(subKeyCheck == RegistryKeyPermissionCheck.Default) { if( checkMode == RegistryKeyPermissionCheck.Default) { if(remoteKey) { CheckUnmanagedCodePermission(); } else { demand = true; GetSubKeyReadPermission(item, out access, out path); } } } break; default: BCLDebug.Assert(false, «CheckPermission default switch case should never be hit!«); break; } if (demand) { new RegistryPermission(access, path).Demand(); } } [System.Security.SecurityCritical] // auto-generated static private void CheckUnmanagedCodePermission() { #pragma warning disable 618 new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); #pragma warning restore 618 } [System.Security.SecurityCritical] // auto-generated private bool ContainsRegistryValue(string name) { int type = 0; int datasize = 0; int retval = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize); return retval == 0; } [System.Security.SecurityCritical] // auto-generated private void EnsureNotDisposed(){ if (hkey == null) { ThrowHelper.ThrowObjectDisposedException(keyName, ExceptionResource.ObjectDisposed_RegKeyClosed); } } [System.Security.SecurityCritical] // auto-generated private void EnsureWriteable() { EnsureNotDisposed(); if (!IsWritable()) { ThrowHelper.ThrowUnauthorizedAccessException(ExceptionResource.UnauthorizedAccess_RegistryNoWrite); } } static int GetRegistryKeyAccess(bool isWritable) { int winAccess; if (!isWritable) { winAccess = Win32Native.KEY_READ; } else { winAccess = Win32Native.KEY_READ | Win32Native.KEY_WRITE; } return winAccess; } static int GetRegistryKeyAccess(RegistryKeyPermissionCheck mode) { int winAccess = 0; switch(mode) { case RegistryKeyPermissionCheck.ReadSubTree: case RegistryKeyPermissionCheck.Default: winAccess = Win32Native.KEY_READ; break; case RegistryKeyPermissionCheck.ReadWriteSubTree: winAccess = Win32Native.KEY_READ| Win32Native.KEY_WRITE; break; default: BCLDebug.Assert(false, «unexpected code path«); break; } return winAccess; } private RegistryKeyPermissionCheck GetSubKeyPermissonCheck(bool subkeyWritable) { if( checkMode == RegistryKeyPermissionCheck.Default) { return checkMode; } if(subkeyWritable) { return RegistryKeyPermissionCheck.ReadWriteSubTree; } else { return RegistryKeyPermissionCheck.ReadSubTree; } } static private void ValidateKeyName(string name) { Contract.Ensures(name != null); if (name == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); } int nextSlash = name.IndexOf(«\«, StringComparison.OrdinalIgnoreCase); int current = 0; while (nextSlash != 1) { if ((nextSlash current) > MaxKeyLength) ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegKeyStrLenBug); current = nextSlash + 1; nextSlash = name.IndexOf(«\«, current, StringComparison.OrdinalIgnoreCase); } if ((name.Length current) > MaxKeyLength) ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegKeyStrLenBug); } static private void ValidateKeyMode(RegistryKeyPermissionCheck mode) { if( mode < RegistryKeyPermissionCheck.Default || mode > RegistryKeyPermissionCheck.ReadWriteSubTree) { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidRegistryKeyPermissionCheck, ExceptionArgument.mode); } } static private void ValidateKeyOptions(RegistryOptions options) { if (options < RegistryOptions.None || options > RegistryOptions.Volatile) { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidRegistryOptionsCheck, ExceptionArgument.options); } } static private void ValidateKeyView(RegistryView view) { if (view != RegistryView.Default && view != RegistryView.Registry32 && view != RegistryView.Registry64) { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidRegistryViewCheck, ExceptionArgument.view); } } #if FEATURE_MACL static private void ValidateKeyRights(int rights) { if(0 != (rights & ~((int)RegistryRights.FullControl))) { // We need to throw SecurityException here for compatiblity reason, // although UnauthorizedAccessException will make more sense. ThrowHelper.ThrowSecurityException(ExceptionResource.Security_RegistryPermission); } } #endif // Win32 constants for error handling private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; } [Flags] public enum RegistryValueOptions { None = 0, DoNotExpandEnvironmentNames = 1 } // the name for this API is meant to mimic FileMode, which has similar values public enum RegistryKeyPermissionCheck { Default = 0, ReadSubTree = 1, ReadWriteSubTree = 2 } #endif // !FEATURE_PAL }

Ситуация:

  • Необходимо получить список всех подразделов определенного раздела реестра.
  • Требуется доступ как к 32-битным, так и к 64-битным программным ключам, поэтому я не могу использовать пространство имен реестра.
  • Использование CSharp в .Net 3.5 и функций реестра из advapi32.dll

У меня работает большая часть функций, но я застрял на ошибке. Когда он достигнет ключа, содержащего значения, он либо пропустит его, либо выдаст следующую ошибку:

  • «Необработанное исключение на 0x00C819CD в xxxxx.exe: 0xC0000005: место записи нарушения прав доступа 0x00720077».

Если ошибка возникает, она не попадает ни в один из моих операторов catch. Это сильно вылетает из программы. Из того, что я читал на форумах, я считаю, что это может быть проблема с записью в защищенную память, но все примеры, которые я вижу, относятся к C ++.

Моя декларация (от P / Invoke Interop Assistant):

    [DllImportAttribute("advapi32.dll", EntryPoint = "RegEnumKeyExW")]
    public static extern int RegEnumKeyExW(
        [InAttribute()] IntPtr hKey, 
        uint dwIndex, 
        [OutAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder lpName, 
        ref uint lpcchName, 
        IntPtr lpReserved, 
        IntPtr lpClass, 
        IntPtr lpcchClass, 
        IntPtr lpftLastWriteTime);

Моя функция (очевидно, работа в процессе, поэтому она немного запутана):

    static private List<string> GetSubKeys(UIntPtr inHive, String inKeyName, RegSAM in32or64key) {
        int hkey = 0;
        uint dwIndex = 0;
        long enumStatus = 0;

        List<string> keys = new List<string>();
        try {
            uint lResult = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                inKeyName,
                0,
                (int)RegSAM.QueryValue | (int)RegSAM.EnumerateSubKeys | (int)in32or64key,
                out hkey);

            if (lResult == 0) {

                while (enumStatus == ERROR_SUCCESS) {
                    StringBuilder lpName = new StringBuilder();
                    uint lpcchName = 256;
                    IntPtr lpReserved = IntPtr.Zero;
                    IntPtr lpClass = IntPtr.Zero;
                    IntPtr lpcchClass = IntPtr.Zero;
                    IntPtr lpftLastWriteTime = IntPtr.Zero;

                    enumStatus = RegEnumKeyExW(
                        (IntPtr)hkey,
                        dwIndex,
                        lpName,
                        ref lpcchName,
                        lpReserved,
                        lpClass,
                        lpcchClass,
                        lpftLastWriteTime);

                    switch (enumStatus) {
                        case ERROR_SUCCESS:
                            Console.WriteLine(string.Format("Key Found: {0}", lpName.ToString()));
                            break;
                        case ERROR_NO_MORE_ITEMS:
                            break;
                        default:
                            string error = new System.ComponentModel.Win32Exception((int)enumStatus).Message;
                            Console.WriteLine(string.Format("RegEnumKeyEx Error: {0}", error));

                            break;
                    }
                    dwIndex++;
                }
            } else {
                Console.WriteLine(string.Format("RegOpenKey Error: {0}", lResult));
            }
        } catch (System.Runtime.InteropServices.COMException ex) {
            Console.WriteLine(string.Format("COM Error: {0}", ex.Message));
        } catch (Exception ex) {
            Console.WriteLine(string.Format("Managed Error: {0}", ex.Message));
        } finally {
            if (0 != hkey) RegCloseKey(hkey);
        }
        return keys;
    }

    #endregion

Используйте так же, как. net4.0

    static void Main(string[] args)
    {
        string displayName;
        List<string> gInstalledSoftware = new List<string>();

        using (var localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
        {
            var key = localMachine.OpenSubKey(@"SOFTWAREMicrosoftWindowsCurrentVersionUninstall", false);
            foreach (String keyName in key.GetSubKeyNames())
            {
                RegistryKey subkey = key.OpenSubKey(keyName);
                displayName = subkey.GetValue("DisplayName") as string;
                if (string.IsNullOrEmpty(displayName))
                    continue;

                gInstalledSoftware.Add(displayName);
            }
        }
    }


0

kongguisheng
31 Янв 2019 в 06:15

Вы можете попробовать использовать. net исходный код для решения этой проблемы. и т.п.

public class RegistryKey:
    IDisposable
    {
    internal static readonly IntPtr HKEY_CLASSES_ROOT = new IntPtr(unchecked((int)0x80000000));
    internal static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001));
    internal static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002));
    internal static readonly IntPtr HKEY_USERS = new IntPtr(unchecked((int)0x80000003));
    internal static readonly IntPtr HKEY_PERFORMANCE_DATA = new IntPtr(unchecked((int)0x80000004));
    internal static readonly IntPtr HKEY_CURRENT_CONFIG = new IntPtr(unchecked((int)0x80000005));

    private static readonly String[] hkeyNames = new String[] {
            "HKEY_CLASSES_ROOT",
            "HKEY_CURRENT_USER",
            "HKEY_LOCAL_MACHINE",
            "HKEY_USERS",
            "HKEY_PERFORMANCE_DATA",
            "HKEY_CURRENT_CONFIG",
            };

    public Object GetValue(String name)
    {
        return InternalGetValue(name, null, false, true);
    }

    internal Object InternalGetValue(String name, Object defaultValue, bool doNotExpand, bool checkSecurity)
    {
        Object data = defaultValue;
        int type = 0;
        int datasize = 0;

        int ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize);

        if (ret != 0)
        {
            if (IsPerfDataKey())
            {
                int size = 65000;
                int sizeInput = size;

                int r;
                byte[] blob = new byte[size];
                while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput)))
                {
                    if (size == Int32.MaxValue)
                    {
                        // ERROR_MORE_DATA was returned however we cannot increase the buffer size beyond Int32.MaxValue
                        //Win32Error(r, name);
                        Console.WriteLine(string.Format("[{0}] [{1}]", r,name));
                    }
                    else if (size > (Int32.MaxValue / 2))
                    {
                        // at this point in the loop "size * 2" would cause an overflow
                        size = Int32.MaxValue;
                    }
                    else
                    {
                        size *= 2;
                    }
                    sizeInput = size;
                    blob = new byte[size];
                }
                if (r != 0)
                    Console.WriteLine(string.Format("[{0}] [{1}]", r, name));
                return blob;
            }
            else
            {
                // For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data).
                // Some OS's returned ERROR_MORE_DATA even in success cases, so we 
                // want to continue on through the function. 
                if (ret != Win32Native.ERROR_MORE_DATA)
                    return data;
            }
        }

        if (datasize < 0)
        {
            // unexpected code path
            //BCLDebug.Assert(false, "[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize");
            datasize = 0;
        }


        switch (type)
        {
            case Win32Native.REG_NONE:
            case Win32Native.REG_DWORD_BIG_ENDIAN:
            case Win32Native.REG_BINARY:
                {
                    byte[] blob = new byte[datasize];
                    ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
                    data = blob;
                }
                break;
            case Win32Native.REG_QWORD:
                {    // also REG_QWORD_LITTLE_ENDIAN
                    if (datasize > 8)
                    {
                        // prevent an AV in the edge case that datasize is larger than sizeof(long)
                        goto case Win32Native.REG_BINARY;
                    }
                    long blob = 0;
                    //BCLDebug.Assert(datasize==8, "datasize==8");
                    // Here, datasize must be 8 when calling this
                    ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize);

                    data = blob;
                }
                break;
            case Win32Native.REG_DWORD:
                {    // also REG_DWORD_LITTLE_ENDIAN
                    if (datasize > 4)
                    {
                        // prevent an AV in the edge case that datasize is larger than sizeof(int)
                        goto case Win32Native.REG_QWORD;
                    }
                    int blob = 0;
                    // Here, datasize must be four when calling this
                    ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize);

                    data = blob;
                }
                break;

            case Win32Native.REG_SZ:
                {
                    if (datasize % 2 == 1)
                    {
                        // handle the case where the registry contains an odd-byte length (corrupt data?)
                        try
                        {
                            datasize = checked(datasize + 1);
                        }
                        catch (OverflowException e)
                        {
                            throw new IOException(("Arg_RegGetOverflowBug"), e);
                        }
                    }
                    char[] blob = new char[datasize / 2];

                    ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
                    if (blob.Length > 0 && blob[blob.Length - 1] == (char)0)
                    {
                        data = new String(blob, 0, blob.Length - 1);
                    }
                    else
                    {
                        // in the very unlikely case the data is missing null termination, 
                        // pass in the whole char[] to prevent truncating a character
                        data = new String(blob);
                    }
                }
                break;

            case Win32Native.REG_EXPAND_SZ:
                {
                    if (datasize % 2 == 1)
                    {
                        // handle the case where the registry contains an odd-byte length (corrupt data?)
                        try
                        {
                            datasize = checked(datasize + 1);
                        }
                        catch (OverflowException e)
                        {
                            throw new IOException(("Arg_RegGetOverflowBug"), e);
                        }
                    }
                    char[] blob = new char[datasize / 2];

                    ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);

                    if (blob.Length > 0 && blob[blob.Length - 1] == (char)0)
                    {
                        data = new String(blob, 0, blob.Length - 1);
                    }
                    else
                    {
                        // in the very unlikely case the data is missing null termination, 
                        // pass in the whole char[] to prevent truncating a character
                        data = new String(blob);
                    }

                    if (!doNotExpand)
                        data = Environment.ExpandEnvironmentVariables((String)data);
                }
                break;
            case Win32Native.REG_MULTI_SZ:
                {
                    if (datasize % 2 == 1)
                    {
                        // handle the case where the registry contains an odd-byte length (corrupt data?)
                        try
                        {
                            datasize = checked(datasize + 1);
                        }
                        catch (OverflowException e)
                        {
                            throw new IOException(("Arg_RegGetOverflowBug"), e);
                        }
                    }
                    char[] blob = new char[datasize / 2];

                    ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);

                    // make sure the string is null terminated before processing the data
                    if (blob.Length > 0 && blob[blob.Length - 1] != (char)0)
                    {
                        try
                        {
                            char[] newBlob = new char[checked(blob.Length + 1)];
                            for (int i = 0; i < blob.Length; i++)
                            {
                                newBlob[i] = blob[i];
                            }
                            newBlob[newBlob.Length - 1] = (char)0;
                            blob = newBlob;
                        }
                        catch (OverflowException e)
                        {
                            throw new IOException(("Arg_RegGetOverflowBug"), e);
                        }
                        blob[blob.Length - 1] = (char)0;
                    }


                    IList<String> strings = new List<String>();
                    int cur = 0;
                    int len = blob.Length;

                    while (ret == 0 && cur < len)
                    {
                        int nextNull = cur;
                        while (nextNull < len && blob[nextNull] != (char)0)
                        {
                            nextNull++;
                        }

                        if (nextNull < len)
                        {
                            //BCLDebug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0");
                            if (nextNull - cur > 0)
                            {
                                strings.Add(new String(blob, cur, nextNull - cur));
                            }
                            else
                            {
                                // we found an empty string.  But if we're at the end of the data, 
                                // it's just the extra null terminator. 
                                if (nextNull != len - 1)
                                    strings.Add(String.Empty);
                            }
                        }
                        else
                        {
                            strings.Add(new String(blob, cur, len - cur));
                        }
                        cur = nextNull + 1;
                    }

                    data = new String[strings.Count];
                    strings.CopyTo((String[])data, 0);
                }
                break;
            case Win32Native.REG_LINK:
            default:
                break;
        }

        return data;
    }

    public String[] GetSubKeyNames()
    {
        return InternalGetSubKeyNames();
    }

    public RegistryKey OpenSubKey(string name, bool writable=false)
    {
        name = FixupName(name); // Fixup multiple slashes to a single slash            

        SafeRegistryHandle result = null;
        int ret = Win32Native.RegOpenKeyEx(hkey,
            name,
            0,
            GetRegistryKeyAccess(writable) | (int)regView,
            out result);

        if (ret == 0 && !result.IsInvalid)
        {
            RegistryKey key = new RegistryKey(result, writable, false, remoteKey, false, regView);
            key.checkMode = GetSubKeyPermissonCheck(writable);
            key.keyName = keyName + "\" + name;
            return key;
        }

        // Return null if we didn't find the key.
        if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL)
        {
            // We need to throw SecurityException here for compatibility reasons,
            // although UnauthorizedAccessException will make more sense.
            //ThrowHelper.ThrowSecurityException(ExceptionResource.Security_RegistryPermission);
        }

        return null;
    }

    private const int MaxKeyLength = 255;
    internal unsafe String[] InternalGetSubKeyNames()
    {
        int subkeys = InternalSubKeyCount();
        String[] names = new String[subkeys];  // Returns 0-length array if empty.

        if (subkeys > 0)
        {
            char[] name = new char[MaxKeyLength + 1];

            int namelen;

            fixed (char* namePtr = &name[0])
            {
                for (int i = 0; i < subkeys; i++)
                {
                    namelen = name.Length; // Don't remove this. The API's doesn't work if this is not properly initialised.
                    int ret = Win32Native.RegEnumKeyEx(hkey,
                        i,
                        namePtr,
                        ref namelen,
                        null,
                        null,
                        null,
                        null);
                    if (ret != 0)
                        //Win32Error(ret, null);
                        Console.WriteLine(ret);
                    names[i] = new String(namePtr);
                }
            }
        }

        return names;
    }

    internal int InternalSubKeyCount()
    {
        int subkeys = 0;
        int junk = 0;
        int ret = Win32Native.RegQueryInfoKey(hkey,
                                  null,
                                  null,
                                  IntPtr.Zero,
                                  ref subkeys,  // subkeys
                                  null,
                                  null,
                                  ref junk,     // values
                                  null,
                                  null,
                                  null,
                                  null);

        if (ret != 0)
            //Win32Error(ret, null);
            Console.WriteLine(ret);
        return subkeys;
    }
    public static RegistryKey OpenBaseKey(RegistryHive hKey, RegistryView view)
    {
        return GetBaseKey((IntPtr)((int)hKey), view);
    }

    internal static RegistryKey GetBaseKey(IntPtr hKey, RegistryView view)
    {
        int index = ((int)hKey) & 0x0FFFFFFF;
        //BCLDebug.Assert(index >= 0  && index < hkeyNames.Length, "index is out of range!");
        //BCLDebug.Assert((((int)hKey) & 0xFFFFFFF0) == 0x80000000, "Invalid hkey value!");

        bool isPerf = hKey == HKEY_PERFORMANCE_DATA;
        // only mark the SafeHandle as ownsHandle if the key is HKEY_PERFORMANCE_DATA.
        SafeRegistryHandle srh = new SafeRegistryHandle(hKey, isPerf);

        RegistryKey key = new RegistryKey(srh, true, true, false, isPerf, view);
        key.checkMode = RegistryKeyPermissionCheck.Default;
        key.keyName = hkeyNames[index];
        return key;
    }

    private volatile SafeRegistryHandle hkey = null;
    private volatile int state = 0;
    private volatile String keyName;
    private volatile bool remoteKey = false;
    private volatile RegistryKeyPermissionCheck checkMode;
    private volatile RegistryView regView = RegistryView.Default;

    private const int STATE_DIRTY = 0x0001;

    // SystemKey indicates that this is a "SYSTEMKEY" and shouldn't be "opened"
    // or "closed".
    //
    private const int STATE_SYSTEMKEY = 0x0002;

    // Access
    //
    private const int STATE_WRITEACCESS = 0x0004;

    // Indicates if this key is for HKEY_PERFORMANCE_DATA
    private const int STATE_PERF_DATA = 0x0008;

    private RegistryKey(SafeRegistryHandle hkey, bool writable, bool systemkey, bool remoteKey, bool isPerfData, RegistryView view)
    {
        this.hkey = hkey;
        this.keyName = "";
        this.remoteKey = remoteKey;
        this.regView = view;
        if (systemkey)
        {
            this.state |= STATE_SYSTEMKEY;
        }
        if (writable)
        {
            this.state |= STATE_WRITEACCESS;
        }
        if (isPerfData)
            this.state |= STATE_PERF_DATA;
    }

    private RegistryKeyPermissionCheck GetSubKeyPermissonCheck(bool subkeyWritable)
    {
        if (checkMode == RegistryKeyPermissionCheck.Default)
        {
            return checkMode;
        }

        if (subkeyWritable)
        {
            return RegistryKeyPermissionCheck.ReadWriteSubTree;
        }
        else
        {
            return RegistryKeyPermissionCheck.ReadSubTree;
        }
    }

    static int GetRegistryKeyAccess(bool isWritable)
    {
        int winAccess;
        if (!isWritable)
        {
            winAccess = Win32Native.KEY_READ;
        }
        else
        {
            winAccess = Win32Native.KEY_READ | Win32Native.KEY_WRITE;
        }

        return winAccess;
    }

    internal static String FixupName(String name)
    {
        //BCLDebug.Assert(name!=null,"[FixupName]name!=null");
        if (name.IndexOf('\') == -1)
            return name;

        StringBuilder sb = new StringBuilder(name);
        FixupPath(sb);
        int temp = sb.Length - 1;
        if (temp >= 0 && sb[temp] == '\') // Remove trailing slash
            sb.Length = temp;
        return sb.ToString();
    }

    private static void FixupPath(StringBuilder path)
    {
        //Contract.Requires(path != null);
        int length = path.Length;
        bool fixup = false;
        char markerChar = (char)0xFFFF;

        int i = 1;
        while (i < length - 1)
        {
            if (path[i] == '\')
            {
                i++;
                while (i < length)
                {
                    if (path[i] == '\')
                    {
                        path[i] = markerChar;
                        i++;
                        fixup = true;
                    }
                    else
                        break;
                }

            }
            i++;
        }

        if (fixup)
        {
            i = 0;
            int j = 0;
            while (i < length)
            {
                if (path[i] == markerChar)
                {
                    i++;
                    continue;
                }
                path[j] = path[i];
                i++;
                j++;
            }
            path.Length += j - i;
        }

    }

    #region IDisposable Support
    private bool disposedValue = false; // 要检测冗余调用

    public void Close()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (hkey != null)
        {

            if (!IsSystemKey())
            {
                try
                {
                    hkey.Dispose();
                }
                catch (IOException)
                {
                    // we don't really care if the handle is invalid at this point
                }
                finally
                {
                    hkey = null;
                }
            }
            else if (disposing && IsPerfDataKey())
            {
                // System keys should never be closed.  However, we want to call RegCloseKey
                // on HKEY_PERFORMANCE_DATA when called from PerformanceCounter.CloseSharedResources
                // (i.e. when disposing is true) so that we release the PERFLIB cache and cause it
                // to be refreshed (by re-reading the registry) when accessed subsequently. 
                // This is the only way we can see the just installed perf counter.  
                // NOTE: since HKEY_PERFORMANCE_DATA is process wide, there is inherent race condition in closing
                // the key asynchronously. While Vista is smart enough to rebuild the PERFLIB resources
                // in this situation the down level OSes are not. We have a small window between  
                // the dispose below and usage elsewhere (other threads). This is By Design. 
                // This is less of an issue when OS > NT5 (i.e Vista & higher), we can close the perfkey  
                // (to release & refresh PERFLIB resources) and the OS will rebuild PERFLIB as necessary. 
                SafeRegistryHandle.RegCloseKey(RegistryKey.HKEY_PERFORMANCE_DATA);
            }
        }
    }

    private bool IsPerfDataKey()
    {
        return (this.state & STATE_PERF_DATA) != 0;
    }

    private bool IsSystemKey()
    {
        return (this.state & STATE_SYSTEMKEY) != 0;
    }

    public void Dispose()
    {
        Dispose(true);
    }
    #endregion
}

[System.Security.SecurityCritical]
public sealed class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    [System.Security.SecurityCritical]
    internal SafeRegistryHandle() : base(true) { }

    [System.Security.SecurityCritical]
    public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle)
    {
        SetHandle(preexistingHandle);
    }

    [System.Security.SecurityCritical]
    override protected bool ReleaseHandle()
    {
        return (RegCloseKey(handle) == Win32Native.ERROR_SUCCESS);
    }

    [DllImport(Win32Native.ADVAPI32)]
    internal static extern int RegCloseKey(IntPtr hKey);
}

[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public enum RegistryHive
{
    ClassesRoot = unchecked((int)0x80000000),
    CurrentUser = unchecked((int)0x80000001),
    LocalMachine = unchecked((int)0x80000002),
    Users = unchecked((int)0x80000003),
    PerformanceData = unchecked((int)0x80000004),
    CurrentConfig = unchecked((int)0x80000005),
}

public enum RegistryView
{
    Default = 0,                           // 0x0000 operate on the default registry view
    Registry64 = Win32Native.KEY_WOW64_64KEY, // 0x0100 operate on the 64-bit registry view
    Registry32 = Win32Native.KEY_WOW64_32KEY, // 0x0200 operate on the 32-bit registry view
};

public enum RegistryKeyPermissionCheck
{
    Default = 0,
    ReadSubTree = 1,
    ReadWriteSubTree = 2
}

public static class Win32Native
{
    internal const String ADVAPI32 = "advapi32.dll";

    internal const int KEY_WOW64_64KEY = 0x0100;     //
    internal const int KEY_WOW64_32KEY = 0x0200;     //
    internal const int ERROR_SUCCESS = 0x0;

    internal const int READ_CONTROL = 0x00020000;
    internal const int SYNCHRONIZE = 0x00100000;

    internal const int STANDARD_RIGHTS_READ = READ_CONTROL;
    internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL;

    internal const int KEY_QUERY_VALUE = 0x0001;
    internal const int KEY_SET_VALUE = 0x0002;
    internal const int KEY_CREATE_SUB_KEY = 0x0004;
    internal const int KEY_ENUMERATE_SUB_KEYS = 0x0008;
    internal const int KEY_NOTIFY = 0x0010;
    internal const int KEY_CREATE_LINK = 0x0020;
    internal const int KEY_READ = ((STANDARD_RIGHTS_READ |
                                                       KEY_QUERY_VALUE |
                                                       KEY_ENUMERATE_SUB_KEYS |
                                                       KEY_NOTIFY)
                                                      &
                                                      (~SYNCHRONIZE));

    internal const int KEY_WRITE = ((STANDARD_RIGHTS_WRITE |
                                                       KEY_SET_VALUE |
                                                       KEY_CREATE_SUB_KEY)
                                                      &
                                                      (~SYNCHRONIZE));

    internal const int ERROR_ACCESS_DENIED = 0x5;
    internal const int ERROR_BAD_IMPERSONATION_LEVEL = 0x542;

    [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
    internal static extern int RegOpenKeyEx(SafeRegistryHandle hKey, String lpSubKey,
        int ulOptions, int samDesired, out SafeRegistryHandle hkResult);
    [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
    internal static extern int RegQueryInfoKey(SafeRegistryHandle hKey, [Out]StringBuilder lpClass,
        int[] lpcbClass, IntPtr lpReserved_MustBeZero, ref int lpcSubKeys,
        int[] lpcbMaxSubKeyLen, int[] lpcbMaxClassLen,
        ref int lpcValues, int[] lpcbMaxValueNameLen,
        int[] lpcbMaxValueLen, int[] lpcbSecurityDescriptor,
        int[] lpftLastWriteTime);

    [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
    internal unsafe static extern int RegEnumKeyEx(SafeRegistryHandle hKey, int dwIndex,
        char* lpName, ref int lpcbName, int[] lpReserved,
        [Out]StringBuilder lpClass, int[] lpcbClass,
        long[] lpftLastWriteTime);


    internal const int ERROR_MORE_DATA = 0xEA;
    internal const int REG_NONE = 0;     // No value type
    internal const int REG_DWORD_BIG_ENDIAN = 5;     // 32-bit number
    internal const int REG_BINARY = 3;     // Free form binary
    internal const int REG_QWORD = 11;    // 64-bit number
    internal const int REG_DWORD = 4;     // 32-bit number
    internal const int REG_SZ = 1;     // Unicode nul terminated string
    internal const int REG_EXPAND_SZ = 2;     // Unicode nul terminated string
    internal const int REG_MULTI_SZ = 7;     // Multiple Unicode strings
    internal const int REG_LINK = 6;     // Symbolic Link (unicode)
    [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
    internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
                        int[] lpReserved, ref int lpType, [Out] byte[] lpData,
                        ref int lpcbData);

    [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
    internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
                int[] lpReserved, ref int lpType, ref int lpData,
                ref int lpcbData);

    [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
    internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
                int[] lpReserved, ref int lpType, ref long lpData,
                ref int lpcbData);

    [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
    internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
                 int[] lpReserved, ref int lpType, [Out] char[] lpData,
                 ref int lpcbData);

    [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
    internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
                int[] lpReserved, ref int lpType, [Out]StringBuilder lpData,
                ref int lpcbData);
}


0

Pengyy
31 Янв 2019 в 06:35

lmike

lmike

нет, пердело совершенство


  • #1

я тут думал-подумал…
очередной раз упёршись рогом…, имеем программу/код, имеем домину/нотес, хотим запустить код
НО платформа LDN, в силу многих причин, сделать этого не может (полноценно) в моём случае — это java
Проблемы с жвм домины я пересказывать здесь не буду
Ряд ограничений:
— никаких аппсерверов
— получить данные по результатам работы кода в домину (например в агент)

Решение созрело неожиданно ;) — программа может выдавать результаты в консоль. С т.з. обмена данными — это ничем не отличается от того же http запроса.
Т.е. мы пишем в консоль, а домина забирает из неё результат, дело за малым — контролируемый запуск и парсинг результатов
решать будем… в джава (доминошной)

нам расколоть его поможет киножурнал

кусок

Java:

       String launch=javaApp;
       launch=javaApp + jvmparams +" -jar " + classPath +jar;
       System.out.println("launch:"+launch);
 
       /* call the Hello class */
       try
       {
           theProcess = Runtime.getRuntime().exec(launch);
           /*OutputStream strmOut=theProcess.getOutputStream();*/
       }
       catch(IOException e)
       {
          System.err.println("Error on exec() method");
          e.printStackTrace();
       }
       return theProcess;

хы — скажут мне — удивил запуском программы
тут есть тонкость — получение stdout процесса theProcess.getInputStream() и опять возможен скепсис — как нам это контролировать?
забегая вперед — из ЛС «тоже хачу»
придётся напрячь программную мысль и

Java:

    static void printProcessInput(InputStream is, boolean bOutSuppress){
        Scanner scan = getScanner(is);
        System.out.println("! *Console output:" + !bOutSuppress);
        for (ScanResult res;(res=intercept(scan,".*",bOutSuppress)).isHasNext();){

        }
/*
        while(scan.hasNextLine()){
            String line = scan.nextLine();
              if (!bOutSuppress)
                  System.out.println(line);
        }
  
*/    }

в каментах вариант без разрыва цикла и он в ЛС не подойдёт — «мыто хочем» не массив (который может быть немерянным) получить, а поток и здесь его и получаем, а итерацию вынесем на уровень ЛС
мы уже почти получили желаемое вот она (подготовка)

Java:

    public static ScanResult intercept(Scanner scan, String regex, boolean bOutSuppress){
        boolean hasNext=scan.hasNextLine();
        ScanResult res=new ScanResult("",hasNext);
        if(hasNext){
            String s = scan.nextLine();
            res.setText(s);
            if (!bOutSuppress)
                System.out.println(s);
            Pattern p= Pattern.compile(regex,Pattern.CASE_INSENSITIVE );
            Matcher matcher = p.matcher(s);
            if (matcher.find())res.setRes(s);
        }
        return res;
    }

Потенциально (при больших перерывах в получении из потока) — рискуем схватить таймаут в приложении (а именно его мы запустили выше)
Но не будем доводить до абсурда ;)
Можно заметить — regex — именно оно позволит фильтровать «нужное» из потока (для отладки — нам и весь поток нужен)
ответный кусок в ЛС

Visual Basic:

    Function testProc()
        On Error GoTo ErrH
        GoTo Begin
ErrH:
        Error Err, RaiseError
Begin:
        Dim theProcess As JavaObject, scanRes As JavaObject, scan As Javaobject, errScan As Javaobject
        Set theProcess = getRuntime(me.userJDK, me.classPath, me.jar, me.jvmparams)

        Set scan=rtuObj.getScanner(theProcess.getInputStream())
        Set errScan=rtuObj.getScanner(theProcess.getErrorStream())

        Dim res() As String, cnt As Long
        'scanning program consiole output
        Do
            'set filter for lines to be accepted, true for skiping stdout from java
            Set scanRes=rtuObj.intercept(scan, regexTag, Not me.isDebug)
            'print programm output here
            DebugInfo scanRes.getText()
            'fillout array by filter
            If Len(scanRes.getRes())>0 Then
                Stop
                ReDim Preserve res(cnt) As String
                res(cnt)=StrRight(scanRes.getRes(),stripTag)
                cnt=cnt+1
            End If
            'break when no lines
            If Not scanRes.isHasNext() Then Exit Do
            'Stop
        Loop
        Stop
        'print out error stream (stderr) if exists
        Dim bErrHeader As Boolean
        bErrHeader=True
        Do
            Set scanRes=rtuObj.intercept(errScan, {.+}, Not me.isDebug)
            Dim txt As String
            txt=scanRes.getText()
            If (Len(txt)>0) And bErrHeader Then
                DebugInfo {*** Errors ***}
                bErrHeader=False
            End If
            DebugInfo txt
            If Not scanRes.isHasNext() Then Exit Do
            Stop
        Loop
      
        testProc=(res)
    End Function

типа УРА
бонусом мы получили замену неработающей регулярно Java Debug Console (при запущенном дизигнере)

по регэкспам — пригодится «отрицание» ;)
хавалук

Ссылка скрыта от гостей

Последнее редактирование: 01.11.2021

lmike

lmike

нет, пердело совершенство


  • #2

продолжу свой опус….
выше — это тупо зауск проги, но без детализации, что ещё возможно:
— передача инфы в потоке — типа пишем в выходной поток проги, она плюёт во входной для кода (в коде выше InputStream). Тонкость — надо коммутировать эти потоки через очередь, примитивный случай (без коммутации) может дать проблемы (типа записали — надо сразу считывать)
— пакетная обработка — проге скармливаем файл с набором строк, каждая строка — набор аргументов

щас опишу рапер для http…
для чего он нужен — блаблабла старая домина/жвм/асинхронная обработка запросов, библиотеки для жвм новее домирношной
кусок основного кода джава (внешней)

Java:

    private static String getStringFromMethod(HttpEntityEnclosingRequestBase method, String bodyJSON, String authToken) throws IOException {
        method.addHeader("content-type", "application/json;charset=UTF-8");
        if (authToken != null) method.addHeader("X-Auth-Token", authToken);

        StringEntity body = new StringEntity(bodyJSON);
        method.setEntity(body);

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            try (CloseableHttpResponse response = httpClient.execute(method)) {
                int status = response.getStatusLine().getStatusCode();
                if (status != STATUS_OK) {
                    LOG.error("n->error:" + status + ";" + response.getStatusLine().getReasonPhrase());
                } else {
                    return resultToFile(EntityUtils.toString(response.getEntity()));
                }
            }
        }
        return null;
    }

а точку входа оформим так

Java:

    public static void main(String[] args) throws IOException {
        String token = null;
        String data = null;
        String method = null;
        String uri = null;
        for (String s : args) {
            if (s.toUpperCase().startsWith(String.valueOf(ARGS.FILE))) {
                data = new BufferedReader(
                        new InputStreamReader(new FileInputStream(s.split("=")[1]), StandardCharsets.UTF_8))
                        .lines()
                        .collect(Collectors.joining("n"));
            } else if (s.toUpperCase().startsWith(String.valueOf(ARGS.DATA))) {
                data = s.split("=")[1];
            } else if (s.toUpperCase().startsWith(String.valueOf(ARGS.METHOD))) {
                method = s.split("=")[1];
            } else if (s.toUpperCase().startsWith(String.valueOf(ARGS.URI))) {
                uri = s.split("=")[1];
            } else if (s.toUpperCase().startsWith(String.valueOf(ARGS.TOKEN))) {
                String[] arr = s.split("=");
                if(arr.length>1)token=arr[1];
            }
        }
        if (uri != null && method != null) {
            switch (method) {
                case "deleteRequestWithAuthToken":
                    if (token == null) token = getToken();
                    if (token != null)
                        deleteRequestWithAuthToken(uri, token);
                    break;
                case "getRequest":
                    if (token == null) token = getToken();
                    if (token != null)
                        getRequest(uri, token);
                    break;
                case "postRequest":
                    if (data != null)
                        postRequest(uri, data);
                    break;
                case "postRequestWithAuthToken":
                    if (token == null) token = getToken();
                    if (token != null && data != null)
                        postRequestWithAuthToken(uri, token, data);
                    break;
                case "PutRequestWithAuthToken":
                    if (token == null) token = getToken();
                    if (token != null && data != null)
                        putRequestWithAuthToken(uri, token, data);
                    break;
                case "getFileRequest":
                    if (token == null) token = getToken();
                    if (token != null && data != null)
                        getFileRequest(uri, token, data);
            }
        }
    }

как видно — идет вызов методов класса
наворачивать рефлекшн и контроль параметров и имен я тупо не стал — считаю избыточным
теперь к джава в домине (кусок)

Java:

    private enum ARGS {FILE, METHOD, URI, DATA, TOKEN, JSON};
    private enum METHODS {deleteRequestWithAuthToken,getRequest,getFileRequest,postRequest,postRequestWithAuthToken,putRequestWithAuthToken};
    public String fileTag="->file";
    public String tokenTag="->token";
    public String txtTag="->text:";
    public String fileRegexp="^-\>text:.+";
    public String tokenRegexp="^-\>text:.+";
    public String txtRegexp="^-\>text:.+";

//.........
       private String json2File(String bodyJSON) throws IOException{
        String res=null;
        Path tmp = Files.createTempFile("res", ".txt");
        PrintWriter pw = new PrintWriter(tmp.toFile());
        pw.println(bodyJSON);
        pw.close();
        //tmp.toFile().deleteOnExit();
        res=tmp.toFile().getAbsolutePath();
        return res;
    }
 
    private String intercept(String args, String regexp){
        Process proc=RuntimeUtils.getRuntime(userJDK,classPath, jar+ args,"");
        Scanner scan=RuntimeUtils.getScanner(proc.getInputStream());
        String ret=null;
        for (ScanResult res;(res=RuntimeUtils.intercept(scan,regexp,true)).isHasNext();){
            String s=res.getRes();
//last by regex
            if (s.length()>0)ret=s;
        }
        RuntimeUtils.printProcessInput(proc.getErrorStream(), false);
        return ret;
    }

    public String getBody(String txt, String regex){
        String res=null;
        Pattern p= Pattern.compile(regex,Pattern.CASE_INSENSITIVE );
        Matcher matcher = p.matcher(txt);
        if (matcher.find()){
            res=txt.substring(txt.lastIndexOf(txtTag)+txtTag.length());
        }
        return res;
    }
//......
    public String PostRequestWithAuthToken(String url, String bodyJSON, String authToken) throws IOException{
        //HttpPost post = new HttpPost("https://api.infologistics.ru/api4/v4/authenticate");
        String args=String.valueOf(ARGS.URI)+"="+url+" "
        +ARGS.TOKEN+"="+authToken + " "
        +ARGS.METHOD+"="+METHODS.postRequestWithAuthToken +" "
        +ARGS.FILE+"="+json2File(bodyJSON);

        String ret=intercept(args,this.txtRegexp);
        if(ret!=null)ret=ret.substring(ret.lastIndexOf(txtTag)+txtTag.length());
 
        return ret==null?"error":ret;
    }

из кусков видно — можно передавать как файл с контентом, так и строку, разумеется для «сложных» данных файл лучше (чтобы при запуске в коммандной строке не произошёл УПС)
момент — регэкспы для разных случаев разные, во внешней «программе» логгер выдает дублируя — текст ответа и в файл

1637229264403.png

их я фильтрую и ищу
ещё логгер надо настраивать на локаль (чтобы было предсказуемо), например для slf4j property будет так

1637229398531.png

из LS2J может отправить так

Visual Basic:

Class TestToken As ErrorHandlerWJ
    rtuCl As JavaClass
    rtuObj As JavaObject
    SystemObj As Javaobject
    fssep As String
    userJDK As String
    jar As String
    ClassPath As String
    '" -XX:+PrintInlining -Xms512m -Xmx1G -Xquickstart -Xverify:none ";//-Xaggressive -Xnoagent -Xzero:j9zip ";
    jvmparams As String
    isDebug As Boolean
    stripTag As String
    regexTag As String
 
    Sub New(xUserJDK As String, xClassPath As String, xJar As String)
        me.regexTag=regexTag
        me.stripTag=stripTag
        me.IsDebug=True
        me.userJDK=xUserJDK
        me.ClassPath=xClassPath
        me.jar=xJar
        Set rtuCl=jSession.Getclass(WRAPPERCLASS)
        Set rtuObj=rtuCl.Createobject
        Dim JavaSystem As JavaClass
        Set JavaSystem=me.jSession.Getclass(SYSTEM_CLASS)
        Set SystemObj=JavaSystem.Createobject()
        me.fssep=me.SystemObj.getProperty({file.separator})
    End Sub
 
    %REM
        Function testAuth
        Description: Comments for Function
    %END REM
    Function testAuth
        On Error GoTo ErrH
        GoTo Begin
ErrH:
        Error Err, RaiseError
Begin:
        Dim s As String
        s=rtuObj.PostRequest(uri, requestBody)
        MsgBox s
    End Function
End Class

отмечу — вызов из нотусни даст преобразование в 1251 (ибо шинда) и текст на русском будет кракозябрами (если логгер в UTF-8)

Последнее редактирование: 08.12.2021

Понравилась статья? Поделить с друзьями:
  • Error request interception is not enabled
  • Error ret 1002 aqsi
  • Error request from egais service 500 internal server error
  • Error restoring base system hfs imac
  • Error request for member which is of non class type arduino