This is happening due to… (tadaaa…)
A bug in the visual studio debugger!
The debugger reports that the exit code is zero, but the debugger is lying to you and the exit code is in fact non-zero.
The bug is discussed here: https://github.com/dotnet/runtime/issues/35599#issuecomment-621954472
I quote:
The Visual Studio debugger has a quirk that it reports exit code of programs that terminated due to unhandled exceptions as 0 on Windows, but that only happens when you run the program from VS debugger. It does not happen when you run the program from the command line.
(Note how they are calling it a quirk instead of a bug; the hubris of this company is mind-boggling.)
Try running your program from a batch file and display %errorlevel%
to see the real exit code.
Wait, it gets better!
If you use a batch file to see the exit code, you might be surprised to discover that it is still not the value you chose; instead, it is -532462766.
That’s right, the exit code is -532462766.
Not 0, not 42, not -532462765, but exactly -532462766.
WTF, right?
In 32-bit hex, this number is 0xE0434352, which is a nameless, largely undocumented, blanket HRESULT that basically stands for «error due to some unspecified application-specific reasons, we are not telling you exactly what.» In this case, the application-specific reason is that an unhandled DotNet exception caused the process to crash. Rumor has it that this HRESULT is known as «EXCEPTION_COMPLUS» or «CLR_EXCEPTION_V4», although good luck finding a shred of documentation for that. (Also, I could claim that the last 3 hex digits spell «CCR», which constitutes a reference to a well known rock band of the 70ies, good luck refuting my claim!)
Wait, it gets even better!
At this point you might be tempted to try various ways of coercing windows to report an exit code of your own choice instead of the nonsensical -532462766 exit code. You might try:
- catching the exception and setting
ExitCode
before rethrowing it; - catching the exception and invoking
Environment.Exit()
passing your own exit code; - registering an AppDomain unhandled exception handler and setting
ExitCode
in there; - registering an AppDomain unhandled exception handler and invoking
Environment.Exit()
with your own exit code from within the handler;
etc.
It will all be a waste of time. None of it will work. Microsoft has gone to great lengths to make damn sure that in the event of an unhandled exception, a DotNet process will terminate with exit code -532462766 and nothing but exit code -532462766.
-532462766 should be enough for everyone.
Командная строка, исключения
Внимание: этот раздел напрямую связан с выполнением второго практического задания «Разработка утилиты командной строки».
Пример его выполнения на Java и Kotlin см.
в этом же репозитории.
Консольное приложение (программа), основные понятия.
Это практическое задание будет первым для нас, где мы разрабатываем полноценное приложение (а не отдельную функцию или класс). Вопреки общепринятому мнению, консольных приложений сейчас разрабатывается довольно много. Часто вы пользуетесь ими, сами не замечая этого. Например, во время работы Intellij IDEA вы постоянно пользуетесь компилятором Java (javac), компилятором Kotlin (kotlinc), Git клиентом, Maven или Gradle клиентом и так далее. Все эти приложения — консольные, а Intellij IDEA обеспечивает удобную графическую оболочку для взаимодействия с ними.
Что же такое «консольное приложение» и что такое консоль? Если объяснять на пальцах, то консольное приложение не использует графическую оболочку и какие-либо графические элементы. Для взаимодействия с пользователем (ввода-вывода) оно использует консоль — место, куда выводится информация от приложения (например, с помощью функции println
) и одновременно место, где пользователь по запросу от приложения может что-нибудь ответить (например, с помощью функции readLine
в Kotlin или с помощью методов System.in
в Java). Возможность ввода информации пользователем, впрочем, в современных консольных приложениях используется довольно редко.
Вы хотите увидеть, как выглядит консоль (она же — терминал)? К ней можно получить доступ разными способами. Например, внутри Intellij IDEA доступ к ней обеспечивается комбинацией Alt-F12 (View > Tool Windows > Terminal), и там она имеет вид однотонного окна в нижней части экрана с приглашающей надписью вида
Microsoft Windows [Version 10.0.18362.720]
(c) 2019 Microsoft Corporation. All rights reserved.
G:kotlin>
Консоль также появится в нижней части экрана, если в Intellij IDEA запустить какое-либо приложение или тест (выглядеть она будет при этом немножко по-другому).
В ОС Windows вы можете открыть консоль через приложение Command Prompt
(Главное меню Windows > Набрать cmd
). Там она выглядит, как чёрное окно с заголовком Command Prompt и примерно теми же приглашающими надписями.
Как запустить консольное приложение? Сейчас, когда мы хотим запустить какую-то программу, в 99% случаях мы это делаем щелчком по ярлыку. В принципе, ярлык можно создать и для консольного приложения, но чаще оно запускается напрямую из консоли. Как это делается? Нужно выполнить следующие действия:
-
Открыть консоль (одним из способов, перечисленных выше).
-
Перейти в директорию, где находится файл, запускающий приложение. Приглашение вида
G:kotlin
указывает, в какой директории консоль находится сейчас. Переход в другую директорию делается (в ОС Windows) командой видаcd D:UserProjectsSomeProject
. -
Запустить файл с приложением. В ОС Windows такие исполняемые файлы обычно имеют расширение
.exe
,.com
или.bat
. Для этого в консоли набираются команда видаSomeProject.exe
или простоSomeProject
.
Внимание! Для консольного приложения под JVM (написанного, например, на Java, Kotlin или Scala) третий пункт будет выглядеть несколько по-другому. Всё дело в том, что такие приложения не предназначены для их запуска в операционной системе напрямую, и поэтому компиляторы Java или Kotlin не создают в процессе своей работы исполняемые файлы с расширением .exe
. Вместо этого, генерируются два других вида файлов:
-
.class
файлы содержат скомпилированные в байт-код JVM классы. Для одного класса на Java создаётся один.class
файл, причём это касается не только классов верхнего уровня, но и вложенных или локальных. Иногда компилятор может создавать дополнительные.class
файлы, вообще не соответствующие ни одному из присутствующих в коде классов. Компилятор Kotlin дополнительно создаёт один.class
файл для каждого файла на Kotlin, в котором присутствуют функции верхнего уровня или глобальные переменные (свойства). -
.jar
файл является архивом, в который упаковываются все.class
файлы, появившиеся в результате компиляции вашей программы. Этот файл — самый близкий аналог исполняемого файла, но не для операционной системы, а для JVM. Именно в этом формате чаще всего распространяются JVM-программы (вернее, их исполняемые файлы) и JVM-библиотеки.
Как же запустить JVM-приложение с помощью jar-файла? Для этого в консоли (вместо третьего пункта выше) вы набираете:
java -jar SomeProject.jar
Здесь java.exe
— исполняемый файл виртуальной машины Java (Java Virtual Machine, JVM — отметим, что и она, в данном случае, является аналогом консольного приложения). Этот файл обычно находится в директории вида C:Program FilesJavajdk-11.0.5bin
(точный путь зависит от вашей версии JDK и места её установки). Естественно, что ваш jar-файл будет находиться в другой директории и запускать эту команду вы будете из неё — как же ОС Windows сможет найти исполняемый файл java.exe
?
А ответ таков — через переменную окружения PATH
. Это переменная не программы, а операционной системы. Доступ к ней вы можете получить, нажав Windows-Pause, затем войдя в Advanced System Settings и Environment Variables. В появившемся окне, в нижней его части вы найдёте переменную Path
или PATH
. Её значение — это список директорий, разделённых точкой с запятой, в которых ОС Windows ищет исполняемые файлы программ. Вам необходимо добавить туда директорию, где находится java.exe
(см. абзац выше).
Аргументы командной строки
Выше я упомянул, что современные консольные приложения редко используют возможность ввода информации пользователем. Логичный вопрос — как же тогда они понимают, что именно им делать? Ответ на него — для этой цели они используют аргументы командной строки. Откуда они берутся? Пользователь их вводит, когда запускает консольное приложение. Например, выше в строке java -jar SomeProject.jar
суффикс -jar SomeProject.jar
это как раз и есть аргументы командной строки для приложения java.exe
, при этом программа java.exe
будет считать -jar
нулевым аргументом, а SomeProject.jar
первым, то есть отдельные аргументы разделяются пробелами. В данном случае нулевой аргумент означает, что JVM должна запустить на исполнение именно jar-файл, а первый задаёт конкретное имя этого jar-файла.
Прочитать свои аргументы командной строки JVM-приложение может через главную функцию main
. На Java её заголовок выглядит так:
public class SomeClass { public static void main(String[] args) { // args[0] = нулевой аргумент командной строки, // args[1] = первый и т.д., // args.length = число заданных аргументов } }
А на Kotlin вот так:
fun main(args: Array<String>) { // Смысл args тот же самый }
Для запуска вашей программы с аргументами командной строки из консоли вы набираете:
java -jar SomeProject.jar SomeProjectArgument0 SomeProjectArgument1
указывая нужное вам число аргументов после SomeProject.jar
. JVM при запуске автоматически передаст эти аргументы главной функции вашего приложения.
Вы также можете запустить свою программу из Intellij IDEA напрямую, без создания консоли, но и здесь потребуются некоторые ухищрения. Если вы попробуете запустить свою программу, нажав на «зелёный треугольник» напротив главной функции, то запуск произойдёт, но аргументы командной строки в программу переданы не будут (args.length
будет равно 0) и, если ваша программа ожидает их наличия, в ней произойдёт ошибка. Для того чтобы аргументы командной строки всё-таки передать, необходимо создать так называемую «конфигурацию запуска» (Run Configuration). Для этого:
-
Вначале запустите программу с помощью «зелёного треугольника» обычным образом.
-
После этого в верхней правой части окна IDEA найдите выпадающее меню (Combo Box) слева от иконки с зелёным треугольником, откройте его и выберите пункт «Edit Configurations».
-
В открывшемся окне слева выберите Application > <Название вашего класса или файла с функцией main>, как правило эти пункты будут сверху списка конфигураций. Если ваша программа на Kotlin и файл с главной функцией назывался
Some.kt
, это название будетSomeKt
, на Java название конфигурации в точности соответствует названию класса с главной функцией. -
Заполните пункт
Program arguments
, указав в нём нужные вам аргументы командной строки. -
Нажмите OK.
-
Нажмите на «зелёный треугольник», но не напротив главной функции, а рядом с выпадающим меню, в которое вы только что входили.
Если вы всё сделали правильно, программа запустится с теми аргументами командной строки, которые вы указали.
Создание и настройка проекта консольного приложения в IDEA
Начать выполнение этого задания следует с создания нового проекта. Напомню, что в этом задании мы не используем готовый проект, вроде KotlinAsFirst
, а создаём свой, после чего размещаем его в репозитории на GitHub
(или, если вы хотите, в другом репозитории в Интернете). Intellij IDEA поддерживает несколько видов проектов, и вам необходимо будет выбрать один из них (простой IDEA-проект, Maven-проект или Gradle-проект). Рекомендуемым вариантом является Maven-проект.
Что такое вообще «программный проект» и из чего он состоит? Приблизительно его можно определить как «совокупность файлов, позволяющих скомпилировать и запустить программу», а в состав проекта входят, как минимум:
-
файл(ы), описывающий(е) структуру и настройки проекта (где что находится, какая используется JDK, как всё следует компилировать и так далее)
-
файлы собственно с программой (так называемые source files, или «сорцы», или файлы с исходным кодом —
.java
,.kt
), причём в их число входят production-файлы, непосредственно использующиеся при исполнении программы, и test-файлы, использующиеся только при её автоматическом тестировании -
так называемые «ресурсы» — дополнительные файлы, используемые программой или тестами, например, в текстовом или графическом формате; к этой категории можно (~) отнести каталог
input
вKotlinAsFirst
-
файлы, содержащие зависимости проекта и/или ссылки на них — здесь речь идёт об используемых программой внешних библиотеках, самый простой пример — библиотека
JUnit
, постоянно используемая нами для тестирования, или стандартная библиотека Котлинаkotlin-stdlib
-
скомпилированные файлы проекта (binary files —
.class
,.jar
) — как правило, не хранятся в репозитории, а создаются дополнительно во время компиляции проекта
Итак, создадим новый проект. В любом случае, начинается всё с выполнения команды New Project
.
Простой IDEA-проект
Такой проект описывает свою структуру исключительно с помощью внутренних файлов Intellij IDEA, и хранит свои зависимости непосредственно, внутри самого проекта. Для создания такого проекта в окне New Project
необходимо выбрать пункт «Java». Если вы собираетесь писать на Kotlin, в списке «Additional Libraries and Frameworks» необходимо поставить галочку напротив пункта «Kotlin/JVM» (в нижней части списка) — или же вы можете выбрать пункт «Kotlin» в исходном окне и пункт «JVM/IDEA» в появившемся списке. Далее IDEA предложит вам выбрать имя, положение и JDK проекта, после чего проект будет создан.
Подобный проект прост в том смысле, что его использование требует минимального изучения инструментов. Сложность его в том, что все зависимости (в частности, JUnit
, kotlin-stdlib
, args4j
, если она вам потребуеся — см. ниже) ваш проект будет хранить в поддиректории lib
, причём kotlin-stdlib
там будет находиться изначально, а остальные библиотеки вам придётся скачать туда самостоятельно. Проще всего это делается через меню File > Project Structure > Libraries > + > From Maven, после чего вам будет предложено найти библиотеку по её названию и скачать её из Maven-репозитороя (большое хранилище библиотек Java). Можно также вместо «From Maven» выбрать пункт «Jar» и затем выбрать jar-файл библиотеки, скачанный самостоятельно.
Простой IDEA-проект обычно хранит исходные файлы (source files) в поддиректориях src
(обычно подсвечивается синим) и test
(обычно подсвечивается зелёным).
Maven-проект
Этот проект описывает свою структуру с помощью файла pom.xml
системы сборки проектов Maven
. Такую структуру, в частности, используют проекты KotlinAsFirst
и данный проект FromKotlinToJava
. Для создания этого проекта выберите в окне New Project
вид проекта Maven
. Если вам нужен проект с использованием Kotlin, проще всего поставить галочку «Create from archetype», выбрать в списке пункт org.jetbrains.kotlin:kotlin-archetype-jvm
(внимание: не путать с kotlin-archetype-js
!) и в нём — наиболее позднюю версию Kotlin, например, 1.3.71 на момент написания этого текста. Нажмите OK, и проект будет создан. Если IDEA предложит вам выполнить импорт Maven-проекта — соглашайтесь.
Maven-проект обычно хранит исходные файлы (source files) в поддиректориях:
* src/main/java
— production Java files
* src/main/kotlin
— production Kotlin files (оба этих каталога обычно подсвечиваются синим)
* src/test/java
— test Java files
* src/test/kotlin
— test Kotlin files (оба этих каталога обычно подсвечиваются зелёным)
Свои зависимости maven-проект описывает непосредственно в файле pom.xml
, а jar-файлы библиотек скачивает из Maven-репозитороя (большое хранилище библиотек Java) в процессе импорта проекта. В качестве примера описания зависимостей вы можете открыть файл pom.xml этого проекта. Например, зависимость от библиотеки JUnit описывается так:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
Здесь groupId
задаёт «группу» библиотеки (в рамках одной группы может существовать несколько разных библиотек), artifactId
— название «артефакта» библиотеки (~ название самой библиотеки), version
конкретную версию и scope
область действия зависимости — здесь test
означает, что библиотека нужна только для тестов, а production
— и для основного кода тоже.
Gradle-проект
Этот проект описывает свою структуру с помощью файла build.gradle
(и некоторых других) системы сборки проектов Gradle
. Эта система замечательна тем, что build.gradle
на самом деле является программой (скриптом, если быть более точным) на языке Groovy, что позволяет ей описывать гораздо более сложную логику настройки и сборки проекта. В качестве примера вы можете посмотреть вот на этот проект, который мы с вами будем использовать в третьем семестре на курсе «Алгоритмы и структуры данных».
Для создания Gradle-проекта выберите в окне New Project
пункт Gradle
, а в списке Additional Libraries and Frameworks поставьте галочки напротив пунктов Java
, а также Kotlin/JVM
, если вам нужен Kotlin. Далее вам предложат выбрать имя и положение проекта, и Gradle-проект будет создан. Если IDEA предложит вам выполнить импорт Gradle-проекта — соглашайтесь. Gradle-проект хранит исходные файлы в тех же поддиректориях, что и Maven-проект (см. выше), и тоже скачивает зависимости из Maven-репозитория, но описывает их внутри build.gradle
по-другому.
Пример описания Gradle-зависимостей (взято из проекта Algorithms):
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib"
testCompile "org.jetbrains.research:kfirst-runner:19.0.2"
testCompile "org.jetbrains.kotlin:kotlin-test"
testCompile "org.jetbrains.kotlin:kotlin-test-junit5"
testCompile "org.junit.jupiter:junit-jupiter-api:5.5.1"
testRuntime "org.junit.jupiter:junit-jupiter-engine:5.5.1"
testRuntime "org.junit.platform:junit-platform-launcher:1.5.1"
}
Здесь, в частности, сказано, что для сборки основной части проекта нужна kotlin-stdlib
, а для тестирования — библиотека kotlin-test-junit5
(версия JUnit, адаптированная под Kotlin) и ещё несколько других библиотек. В частности, kfirst-runner
используется для проведения тестирования в системе Kotoed.
Настройка сборки артефактов
Создав проект тем или иным образом, напишите в нём простую главную функцию (например, с выводом Hello, world), если этого ещё не сделано в созданном скелете проекта. Выполните Build > Build Project. Убедитесь, что проект собирается, и что вы можете запустить главную функцию «зелёным треугольником». В окне проекта (Alt-1) найдите созданные class-файлы — например, Maven-проект создаёт их в поддиректории target/classes
. Посмотрите, какие ещё файлы были созданы при создании проекта и его сборке, и убедитесь, что среди них нет jar-файла проекта.
Всё дело в том, что jar-файл с точки зрения IDEA является так называемым артефактом (примерно, это нечто, создаваемое в результате сборки проекта и используемое в дальнейшем), а сборка артефактов требует дополнительной настройки. Скажем, в Maven-проектах это делается с помощью maven-assembly-plugin
— см. соответствующие строки в нижней части pom.xml. Для того, чтобы собрать артефакт в FromKotlinToJava
, необходимо открыть этот проект, открыть окно Maven (View > Tool Windows) и в Lifecycle выполнить команду package
(попробуйте сделать это). После выполнения этой команды вы увидите в target
два jar-файла — один простой (содержащий в себе только class-файлы проекта), а другой, гораздо большего размера — с зависимостями (содержащий в себе также необходимые class-файлы из внешних библиотек).
В простом IDEA-проекте для настройки сборки jar-файла используется команда IDEA Build > Build Artifacts, и далее надо выбрать jar-файл, настроить его положение в структуре проекта и указать главный класс для него. В Gradle
для той же цели используется задача jar
— пример её настройки можно посмотреть, например, здесь.
Используя эти инструкции, попробуйте настроить сборку jar-файла в выбранной вами модели проекта (простой, Maven, Gradle) и собрать его, после чего запустить вашу простую программу из консоли. Убедитесь, что всё получается успешно.
Размещение проекта на GitHub
Разместить проект на GitHub проще всего командами IDEA: VCS > Import into Version Control > Share Project on GitHub. Естественно, для этой цели вам потребуется аккаунт на GitHub. Также, вы можете создать проект на GitHub через Web-интерфейс, склонировать его и потом добавить в него необходимые файлы (но это менее удобно).
При создании репозитория на GitHub следует помнить, что не стоит хранить в нём бинарные файлы и вообще «лишние» файлы, не требующиеся для сборки проекта. К таким файлам однозначно относятся class-файлы, собранные вами jar-файлы, а в Maven- и Gradle-проектах также файлы библиотек, поскольку в этом случае они автоматически скачиваются из Maven-репозитория. Набор файлов, игнорируемых системой Git, может быть задан в файле .gitignore
— см. пример.
Выполнение задания
Во всех заданиях (варианты выдают преподаватели практики) предполагается написать аналог существующей утилиты командной строки для работы с файлами или файловой системой. В задании указано, что утилита должна делать и какие аргументы командной строки влияют на её работу. В примере предполагается написание перекодировщика, читающего файл с заданным именем или путём InputName
в кодировке InputEncoding
и записывающего его содержимое в другой файл OutputName
и в другой кодировке OutputEncoding
. Строка запуска подобного приложения может выглядеть так:
java –jar Recoder.jar –ie InputEncoding -oe OutputEncoding InputName OutputName
Вместо ключа -ie
может фигурировать более длинный --inputEncoding
, а вместо -oe
соответственно --outputEncoding
. Подобные возможности являются традиционными для утилит, работающих с командной строкой.
Разбор командной строки
Принципиально ничто не мешает вам реализовать разбор командной строки «в лоб», читая различные элементы массива args
и анализируя их значения. Если вы пойдёте этим путём, не забывайте, что:
-
аргументы могут идти в различном порядке — например, выше мы можем переставить
-ie InputEncoding
и-oe OutputEncoding
-
у коротких ключей может быть более длинная альтернатива
-
если пользователь запустил приложение, указав некорректные аргументы командной строки, нужно прервать работу приложения и указать пользователю, что именно он сделал не так
Это превращает задачу полного разбора в не очень тривиальную. К счастью, эта задача уже была много раз решена до нас, и нет необходимости решать её самостоятельно. Существует ряд Java-библиотек, решающих её, в том числе рассмотренная в примере org.kohsuke.args4j
. Принципы решения задачи могут быть различными; библиотека args4j
для определения структуры командной строки активно использует аннотации. Порядок работы с ней примерно следующий:
-
Все аргументы командной строки описываются как поля класса — в примере это
RecoderLauncher
— с аннотациями, например,@Option
или@Argument
.@Option
задают параметр с ключом, например,-ie InputEncoding
, а@Argument
параметр без ключа, например,InputName
. Поля должны быть не статическими. -
Перед началом разбора необходимо создать экземпляр данного класса —
RecoderLauncher
. -
Для выполнения разбора необходимо создать
CmdLineParser
, передать ему ссылку на экземплярRecoderLauncher
и вызвать методparseArgument
, передав в него аргументы командной строки. В случае успеха поля класса будут заполнены соответствующими им аргументами. В случае неудачи бросается исключениеCmdLineException
.
Работа с файлами
Про работу с файлами в программах на Kotlin мы довольно много говорили в 1-м семестре (особенно советую посмотреть разделы «За занавесом»). Поскольку Kotlin большей частью использует классы стандартной библиотеки Java — такие, как InputStream
(поток для чтения байтов), InputStreamReader
(поток для чтения символов, знает про кодировку), BufferedReader
(буферизованный поток для чтения строк) — то перечисленные классы мы можем применять и в Java программе.
Стандартная библиотека Kotlin, впрочем, включает и дополнительные функции ввода-вывода, отсутствующие в библиотеке Java — это значит, что в программе на Java эти функции вы использовать не сможете. К таковым относятся, например, File.readLines()
, File.forEachLine { … }
, File.bufferedWriter()
и некоторые другие. Потоки, указанные выше, вам придётся создавать последовательно, например:
FileInputStream inputStream = new FileInputStream(inputName); // inputName = имя или путь к файлу
InputStreamReader reader = new InputStreamReader(inputStream, charsetInput); // charsetInput = кодировка файла
Всё это должно сопровождаться ещё и обработкой соответствующих исключений (подробности в следующем разделе). Пример можно посмотреть в классе Recoder.
Обработка исключений
Внимание: про обработку исключений в программах на Kotlin было довольно много написано здесь в разделе «Обработка исключений». Дальнейший текст касается особенностей обработки исключений в Java-программах.
Java, в отличие от Kotlin, включает деление исключений на checked (проверяемые) и unchecked (непроверяемые), причём, когда вы вызываете в программе метод, который может бросить checked исключение, вы не имеете права игнорировать этот факт. В частности, приведённый выше код
FileInputStream inputStream = new FileInputStream(inputName); // inputName = имя или путь к файлу
InputStreamReader reader = new InputStreamReader(inputStream, charsetInput); // charsetInput = кодировка файла
у вас не скомпилируется, если не обработать проверяемое исключение IOException
. Обработать его можно двумя способами:
-
используя конструкцию
try { … } catch (IOException ex) { … } finally { … }
-
объявив, что ваш метод тоже бросает
IOException
, добавив в конец его заголовкаthrows Exception
Если не сделано ни того, ни другого, вы получите ошибку компиляции «Unhandled exception».
К проверяемым относятся те исключения, которые (грубо говоря) могут возникнуть независимо от наличия в программе каких-либо ошибок. Например, IOException
может появиться, когда какой-либо файл не существует на диске, или же доступ к нему закрыт. Оба эти фактора не зависят от программиста. Формально, исключение является checked, если его класс наследует Exception
, но не наследует RuntimeException
.
В противном случае исключение является unchecked. К ним относятся:
-
наследники
RuntimeException
— обычно их появление спровоцировано ошибками программиста, например,NullPointerException
относится к этому классу -
наследники
Error
— их появление обычно привязано к неразрешимым проблемам в ходе работы виртуальной машины Java, но может быть спровоцировано и ошибками программиста; например,StackOverflowError
может быть вызвано как ошибкой программиста (бесконечная рекурсия), так и реальной нехваткой памяти в стеке JVM
Unchecked исключения тоже можно объявлять в заголовке метода, и тоже можно ловить с помощью catch
, но отсутствие подобных объявлений не является ошибкой компиляции.
Закрытие ресурсов
Ряд объектов в Java требует закрытия — вызова их метода close()
— после окончания работы с ними. Как правило, это связано с особенностями работы операционной системы. В Java таковыми, в частности, являются InputStream
, InputStreamReader
, BufferedReader
. Если код, работающий с этими объектами, может вызвать исключение (чаще всего так и бывает), то закрыть их надо как при появлении исключения, так и при успешном выполнении кода. Существует два основных способа сделать это правильно:
-
вызывать метод
close()
в блокеfinally
, который выполняется как при успешном завершенииtry
, так и при ловле исключения вcatch
-
вообще не вызывать метод
close()
явно, используя вместо этого конструкцию try with resource (в Kotlin вместо неё можно использовать функцию высшего порядкаuse
)
Пример из Recoder.java
:
// try with resource
try (FileInputStream inputStream = new FileInputStream(inputName)) {
try (FileOutputStream outputStream = new FileOutputStream(outputName)) {
return recode(inputStream, outputStream);
}
}
Ресурс, объявленный в заголовке try
, автоматически закрывается по окончании его работы. Формально ресурсом является экземпляр любого класса, реализующего интерфейс Closable
или интерфейс AutoClosable
.
Тестирование
Любая программа должна сопровождаться тестами, проверяющими правильность её работы. В рамках данного приложения тестам, как минимум, должна подвергуться основная логика — в примере класс Recoder
. Опционально вы можете протестировать и логику разбора командной строки, особенно если её вы писали самостоятельно без использования готовых библиотек. Для тестирования проще всего использовать знакомую вам библиотеку JUnit
. Не забудьте подключить её к проекту.
Теперь вы знаете всё, что необходимо для выполнения задания на тему «Утилиты командной строки». Удачи!
Время на прочтение
13 мин
Количество просмотров 75K
Введение
Ошибки, увы, неизбежны, поэтому их обработка занимает очень важное место в программировании. И если алгоритмические ошибки можно выявить и исправить во время написания и тестирования программы, то ошибок времени выполнения избежать нельзя в принципе. Сегодня мы рассмотрим функции стандартной библиотеки (C Standard Library) и POSIX, используемые в обработке ошибок.
Переменная errno и коды ошибок
<errno.h>
errno – переменная, хранящая целочисленный код последней ошибки. В каждом потоке существует своя локальная версия errno, чем и обусловливается её безопасность в многопоточной среде. Обычно errno реализуется в виде макроса, разворачивающегося в вызов функции, возвращающей указатель на целочисленный буфер. При запуске программы значение errno равно нулю.
Все коды ошибок имеют положительные значения, и могут использоваться в директивах препроцессора #if. В целях удобства и переносимости заголовочный файл <errno.h>
определяет макросы, соответствующие кодам ошибок.
Стандарт ISO C определяет следующие коды:
- EDOM – (Error domain) ошибка области определения.
- EILSEQ – (Error invalid sequence) ошибочная последовательность байтов.
- ERANGE – (Error range) результат слишком велик.
Прочие коды ошибок (несколько десятков) и их описания определены в стандарте POSIX. Кроме того, в спецификациях стандартных функций обычно указываются используемые ими коды ошибок и их описания.
Нехитрый скрипт печатает в консоль коды ошибок, их символические имена и описания:
#!/usr/bin/perl
use strict;
use warnings;
use Errno;
foreach my $err (sort keys (%!)) {
$! = eval "Errno::$err";
printf "%20s %4d %sn", $err, $! + 0, $!
}
Если вызов функции завершился ошибкой, то она устанавливает переменную errno в ненулевое значение. Если же вызов прошёл успешно, функция обычно не проверяет и не меняет переменную errno. Поэтому перед вызовом функции её нужно установить в 0
.
Пример:
/* convert from UTF16 to UTF8 */
errno = 0;
n_ret = iconv(icd, (char **) &p_src, &n_src, &p_dst, &n_dst);
if (n_ret == (size_t) -1) {
VJ_PERROR();
if (errno == E2BIG)
fprintf(stderr, " Error : input conversion stopped due to lack of space in the output buffern");
else if (errno == EILSEQ)
fprintf(stderr, " Error : input conversion stopped due to an input byte that does not belong to the input codesetn");
else if (errno == EINVAL)
fprintf(stderr, " Error : input conversion stopped due to an incomplete character or shift sequence at the end of the input buffern");
/* clean the memory */
free(p_out_buf);
errno = 0;
n_ret = iconv_close(icd);
if (n_ret == (size_t) -1)
VJ_PERROR();
return (size_t) -1;
}
Как видите, описания ошибок в спецификации функции iconv()
более информативны, чем в <errno.h>
.
Функции работы с errno
Получив код ошибки, хочется сразу получить по нему её описание. К счастью, ISO C предлагает целый набор полезных функций.
<stdio.h>
void perror(const char *s);
Печатает в stderr содержимое строки s
, за которой следует двоеточие, пробел и сообщение об ошибке. После чего печатает символ новой строки 'n'
.
Пример:
/*
// main.c
// perror example
//
// Created by Ariel Feinerman on 23/03/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc, const char * argv[])
{
// Generate unique filename.
char *file_name = tmpnam((char[L_tmpnam]){0});
errno = 0;
FILE *file = fopen(file_name, "rb");
if (file) {
// Do something useful.
fclose(file);
}
else {
perror("fopen() ");
}
return EXIT_SUCCESS;
}
<string.h>
char* strerror(int errnum);
Возвращает строку, содержащую описание ошибки errnum
. Язык сообщения зависит от локали (немецкий, иврит и даже японский), но обычно поддерживается лишь английский.
/*
// main.c
// strerror example
//
// Created by Ariel Feinerman on 23/03/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, const char * argv[])
{
// Generate unique filename.
char *file_name = tmpnam((char[L_tmpnam]){0});
errno = 0;
FILE *file = fopen(file_name, "rb");
// Save error number.
errno_t error_num = errno;
if (file) {
// Do something useful.
fclose(file);
}
else {
char *errorbuf = strerror(error_num);
fprintf(stderr, "Error message : %sn", errorbuf);
}
return EXIT_SUCCESS;
}
strerror()
не безопасная функция. Во-первых, возвращаемая ею строка не является константной. При этом она может храниться в статической или в динамической памяти в зависимости от реализации. В первом случае её изменение приведёт к ошибке времени выполнения. Во-вторых, если вы решите сохранить указатель на строку, и после вызовите функцию с новым кодом, все прежние указатели будут указывать уже на новую строку, ибо она использует один буфер для всех строк. В-третьих, её поведение в многопоточной среде не определено в стандарте. Впрочем, в QNX она объявлена как thread safe.
Поэтому в новом стандарте ISO C11 были предложены две очень полезные функции.
size_t strerrorlen_s(errno_t errnum);
Возвращает длину строки с описанием ошибки errnum
.
errno_t strerror_s(char *buf, rsize_t buflen, errno_t errnum);
Копирует строку с описание ошибки errnum
в буфер buf
длиной buflen
.
Пример:
/*
// main.c
// strerror_s example
//
// Created by Ariel Feinerman on 23/02/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, const char * argv[])
{
// Generate unique filename.
char *file_name = tmpnam((char[L_tmpnam]){0});
errno = 0;
FILE *file = fopen(file_name, "rb");
// Save error number.
errno_t error_num = errno;
if (file) {
// Do something useful.
fclose(file);
}
else {
#ifdef __STDC_LIB_EXT1__
size_t error_len = strerrorlen_s(errno) + 1;
char error_buf[error_len];
strerror_s(error_buf, error_len, errno);
fprintf(stderr, "Error message : %sn", error_buf);
#endif
}
return EXIT_SUCCESS;
}
Функции входят в Annex K (Bounds-checking interfaces), вызвавший много споров. Он не обязателен к выполнению и целиком не реализован ни в одной из свободных библиотек. Open Watcom C/C++ (Windows), Slibc (GNU libc) и Safe C Library (POSIX), в последней, к сожалению, именно эти две функции не реализованы. Тем не менее, их можно найти в коммерческих средах разработки и системах реального времени, Embarcadero RAD Studio, INtime RTOS, QNX.
Стандарт POSIX.1-2008 определяет следующие функции:
char *strerror_l(int errnum, locale_t locale);
Возвращает строку, содержащую локализованное описание ошибки errnum
, используя locale
. Безопасна в многопоточной среде. Не реализована в Mac OS X, FreeBSD, NetBSD, OpenBSD, Solaris и прочих коммерческих UNIX. Реализована в Linux, MINIX 3 и Illumos (OpenSolaris).
Пример:
/*
// main.c
// strerror_l example – works on Linux, MINIX 3, Illumos
//
// Created by Ariel Feinerman on 23/03/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <locale.h>
int main(int argc, const char * argv[])
{
locale_t locale = newlocale(LC_ALL_MASK, "fr_FR.UTF-8", (locale_t) 0);
if (!locale) {
fprintf(stderr, "Error: cannot create locale.");
exit(EXIT_FAILURE);
}
// Generate unique filename.
char *file_name = tmpnam((char[L_tmpnam]){0});
errno = 0;
FILE *file = fopen(tmpnam(file_name, "rb");
// Save error number.
errno_t error_num = errno;
if (file) {
// Do something useful.
fclose(file);
}
else {
char *error_buf = strerror_l(errno, locale);
fprintf(stderr, "Error message : %sn", error_buf);
}
freelocale(locale);
return EXIT_SUCCESS;
}
Вывод:
Error message : Aucun fichier ou dossier de ce type
int strerror_r(int errnum, char *buf, size_t buflen);
Копирует строку с описание ошибки errnum
в буфер buf
длиной buflen
. Если buflen
меньше длины строки, лишнее обрезается. Безопасна в многоготочной среде. Реализована во всех UNIX.
Пример:
/*
// main.c
// strerror_r POSIX example
//
// Created by Ariel Feinerman on 25/02/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define MSG_LEN 1024
int main(int argc, const char * argv[])
{
// Generate unique filename.
char *file_name = tmpnam((char[L_tmpnam]){0});
errno = 0;
FILE *file = fopen(file_name, "rb");
// Save error number.
errno_t error_num = errno;
if (file) {
// Do something useful.
fclose(file);
}
else {
char error_buf[MSG_LEN];
errno_t error = strerror_r (error_num, error_buf, MSG_LEN);
switch (error) {
case EINVAL:
fprintf (stderr, "strerror_r() failed: invalid error code, %dn", error);
break;
case ERANGE:
fprintf (stderr, "strerror_r() failed: buffer too small: %dn", MSG_LEN);
case 0:
fprintf(stderr, "Error message : %sn", error_buf);
break;
default:
fprintf (stderr, "strerror_r() failed: unknown error, %dn", error);
break;
}
}
return EXIT_SUCCESS;
}
Увы, никакого аналога strerrorlen_s()
в POSIX не определили, поэтому длину строки можно выяснить лишь экспериментальным путём. Обычно 300 символов хватает за глаза. GNU C Library в реализации strerror()
использует буфер длиной в 1024 символа. Но мало ли, а вдруг?
Пример:
/*
// main.c
// strerror_r safe POSIX example
//
// Created by Ariel Feinerman on 23/03/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define MSG_LEN 1024
#define MUL_FACTOR 2
int main(int argc, const char * argv[])
{
// Generate unique filename.
char *file_name = tmpnam((char[L_tmpnam]){0});
errno = 0;
FILE *file = fopen(file_name, "rb");
// Save error number.
errno_t error_num = errno;
if (file) {
// Do something useful.
fclose(file);
}
else {
errno_t error = 0;
size_t error_len = MSG_LEN;
do {
char error_buf[error_len];
error = strerror_r (error_num, error_buf, error_len);
switch (error) {
case 0:
fprintf(stderr, "File : %snLine : %dnCurrent function : %s()nFailed function : %s()nError message : %sn", __FILE__, __LINE__, __func__, "fopen", error_buf);
break;
case ERANGE:
error_len *= MUL_FACTOR;
break;
case EINVAL:
fprintf (stderr, "strerror_r() failed: invalid error code, %dn", error_num);
break;
default:
fprintf (stderr, "strerror_r() failed: unknown error, %dn", error);
break;
}
} while (error == ERANGE);
}
return EXIT_SUCCESS;
}
Вывод:
File : /Users/ariel/main.c
Line : 47
Current function : main()
Failed function : fopen()
Error message : No such file or directory
Макрос assert()
<assert.h>
void assert(expression)
Макрос, проверяющий условие expression
(его результат должен быть числом) во время выполнения. Если условие не выполняется (expression
равно нулю), он печатает в stderr значения __FILE__
, __LINE__
, __func__
и expression
в виде строки, после чего вызывает функцию abort()
.
/*
// main.c
// assert example
//
// Created by Ariel Feinerman on 23/03/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
int main(int argc, const char * argv[]) {
double x = -1.0;
assert(x >= 0.0);
printf("sqrt(x) = %fn", sqrt(x));
return EXIT_SUCCESS;
}
Вывод:
Assertion failed: (x >= 0.0), function main, file /Users/ariel/main.c, line 17.
Если макрос NDEBUG
определён перед включением <assert.h>
, то assert()
разворачивается в ((void) 0)
и не делает ничего. Используется в отладочных целях.
Пример:
/*
// main.c
// assert_example
//
// Created by Ariel Feinerman on 23/03/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
int main(int argc, const char * argv[]) {
double x = -1.0;
assert(x >= 0.0);
printf("sqrt(x) = %fn", sqrt(x));
return EXIT_SUCCESS;
}
Вывод:
sqrt(x) = nan
Функции atexit(), exit() и abort()
<stdlib.h>
int atexit(void (*func)(void));
Регистрирует функции, вызываемые при нормальном завершении работы программы в порядке, обратном их регистрации. Можно зарегистрировать до 32 функций.
_Noreturn void exit(int exit_code);
Вызывает нормальное завершение программы, возвращает в среду число exit_code
. ISO C стандарт определяет всего три возможных значения: 0
, EXIT_SUCCESS
и EXIT_FAILURE
. При этом вызываются функции, зарегистрированные через atexit()
, сбрасываются и закрываются потоки ввода — вывода, уничтожаются временные файлы, после чего управление передаётся в среду. Функция exit()
вызывается в main()
при выполнении return или достижении конца программы.
Главное преимущество exit()
в том, что она позволяет завершить программу не только из main()
, но и из любой вложенной функции. К примеру, если в глубоко вложенной функции выполнилось (или не выполнилось) некоторое условие, после чего дальнейшее выполнение программы теряет всякий смысл. Подобный приём (early exit) широко используется при написании демонов, системных утилит и парсеров. В интерактивных программах с бесконечным главным циклом exit()
можно использовать для выхода из программы при выборе нужного пункта меню.
Пример:
/*
// main.c
// exit example
//
// Created by Ariel Feinerman on 17/03/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void third_2(void)
{
printf("third #2n"); // Does not print.
}
void third_1(void)
{
printf("third #1n"); // Does not print.
}
void second(double num)
{
printf("second : before exit()n"); // Prints.
if ((num < 1.0f) && (num > -1.0f)) {
printf("asin(%.1f) = %.3fn", num, asin(num));
exit(EXIT_SUCCESS);
}
else {
fprintf(stderr, "Error: %.1f is beyond the range [-1.0; 1.0]n", num);
exit(EXIT_FAILURE);
}
printf("second : after exit()n"); // Does not print.
}
void first(double num)
{
printf("first : before second()n")
second(num);
printf("first : after second()n"); // Does not print.
}
int main(int argc, const char * argv[])
{
atexit(third_1); // Register first handler.
atexit(third_2); // Register second handler.
first(-3.0f);
return EXIT_SUCCESS;
}
Вывод:
first : before second()
second : before exit()
Error: -3.0 is beyond the range [-1.0; 1.0]
third #2
third #1
_Noreturn void abort(void);
Вызывает аварийное завершение программы, если сигнал не был перехвачен обработчиком сигналов. Временные файлы не уничтожаются, закрытие потоков определяется реализацией. Самое главное отличие вызовов abort() и exit(EXIT_FAILURE)
в том, что первый посылает программе сигнал SIGABRT
, его можно перехватить и произвести нужные действия перед завершением программы. Записывается дамп памяти программы (core dump file), если они разрешены. При запуске в отладчике он перехватывает сигнал SIGABRT
и останавливает выполнение программы, что очень удобно в отладке.
Пример:
/*
// main.c
// abort example
//
// Created by Ariel Feinerman on 17/02/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void third_2(void)
{
printf("third #2n"); // Does not print.
}
void third_1(void)
{
printf("third #1n"); // Does not print.
}
void second(double num)
{
printf("second : before exit()n"); // Prints.
if ((num < 1.0f) && (num > -1.0f)) {
printf("asin(%.1f) = %.3fn", num, asin(num));
exit(EXIT_SUCCESS);
}
else {
fprintf(stderr, "Error: %.1f is beyond the range [-1.0; 1.0]n", num);
abort();
}
printf("second : after exit()n"); // Does not print.
}
void first(double num)
{
printf("first : before second()n");
second(num);
printf("first : after second()n"); // Does not print.
}
int main(int argc, const char * argv[])
{
atexit(third_1); // register first handler
atexit(third_2); // register second handler
first(-3.0f);
return EXIT_SUCCESS;
}
Вывод:
first : before second()
second : before exit()
Error: -3.0 is beyond the range [-1.0; 1.0]
Abort trap: 6
Вывод в отладчике:
$ lldb abort_example
(lldb) target create "abort_example"
Current executable set to 'abort_example' (x86_64).
(lldb) run
Process 22570 launched: '/Users/ariel/abort_example' (x86_64)
first : before second()
second : before exit()
Error: -3.0 is beyond the range [-1.0; 1.0]
Process 22570 stopped
* thread #1: tid = 0x113a8, 0x00007fff89c01286 libsystem_kernel.dylib`__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x00007fff89c01286 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
-> 0x7fff89c01286 <+10>: jae 0x7fff89c01290 ; <+20>
0x7fff89c01288 <+12>: movq %rax, %rdi
0x7fff89c0128b <+15>: jmp 0x7fff89bfcc53 ; cerror_nocancel
0x7fff89c01290 <+20>: retq
(lldb)
В случае критической ошибки нужно использовать функцию abort()
. К примеру, если при выделении памяти или записи файла произошла ошибка. Любые дальнейшие действия могут усугубить ситуацию. Если завершить выполнение обычным способом, при котором производится сброс потоков ввода — вывода, можно потерять ещё неповрежденные данные и временные файлы, поэтому самым лучшим решением будет записать дамп и мгновенно завершить программу.
В случае же некритической ошибки, например, вы не смогли открыть файл, можно безопасно выйти через exit()
.
Функции setjmp() и longjmp()
Вот мы и подошли к самому интересному – функциям нелокальных переходов. setjmp()
и longjmp()
работают по принципу goto, но в отличие от него позволяют перепрыгивать из одного места в другое в пределах всей программы, а не одной функции.
<setjmp.h>
int setjmp(jmp_buf env);
Сохраняет информацию о контексте выполнения программы (регистры микропроцессора и прочее) в env
. Возвращает 0
, если была вызвана напрямую или value
, если из longjmp()
.
void longjmp(jmp_buf env, int value);
Восстанавливает контекст выполнения программы из env
, возвращает управление setjmp()
и передаёт ей value
.
Пример:
/*
// main.c
// setjmp simple
//
// Created by Ariel Feinerman on 18/02/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void)
{
printf("second : before longjmp()n"); // prints
longjmp(buf, 1); // jumps back to where setjmp was called – making setjmp now return 1
printf("second : after longjmp()n"); // does not prints
// <- Here is the point that is never reached. All impossible cases like your own house in Miami, your million dollars, your nice girl, etc.
}
void first(void)
{
printf("first : before second()n");
second();
printf("first : after second()n"); // does not print
}
int main(int argc, const char * argv[])
{
if (!setjmp(buf))
first(); // when executed, setjmp returned 0
else // when longjmp jumps back, setjmp returns 1
printf("mainn"); // prints
return EXIT_SUCCESS;
}
Вывод:
first : before second()
second : before longjmp()
main
Используя setjmp()
и longjmp
() можно реализовать механизм исключений. Во многих языках высокого уровня (например, в Perl) исключения реализованы через них.
Пример:
/*
// main.c
// exception simple
//
// Created by Ariel Feinerman on 18/02/17.
// Copyright 2017 Feinerman Research, Inc. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <setjmp.h>
#define str(s) #s
static jmp_buf buf;
typedef enum {
NO_EXCEPTION = 0,
RANGE_EXCEPTION = 1,
NUM_EXCEPTIONS
} exception_t;
static char *exception_name[NUM_EXCEPTIONS] = {
str(NO_EXCEPTION),
str(RANGE_EXCEPTION)
};
float asin_e(float num)
{
if ((num < 1.0f) && (num > -1.0f)) {
return asinf(num);
}
else {
longjmp(buf, RANGE_EXCEPTION); // | @throw
}
}
void do_work(float num)
{
float res = asin_e(num);
printf("asin(%f) = %fn", num, res);
}
int main(int argc, const char * argv[])
{
exception_t exc = NO_EXCEPTION;
if (!(exc = setjmp(buf))) { // |
do_work(-3.0f); // | @try
} // |
else { // |
fprintf(stderr, "%s was hadled in %s()n", exception_name[exc], __func__); // | @catch
} // |
return EXIT_SUCCESS;
}
Вывод:
RANGE_EXCEPTION was hadled in main()
Внимание! Функции setjmp()
и longjmp
() в первую очередь применяются в системном программировании, и их использование в клиентском коде не рекомендуется. Их применение ухудшает читаемость программы и может привести к непредсказуемым ошибкам. Например, что произойдёт, если вы прыгните не вверх по стеку – в вызывающую функцию, а в параллельную, уже завершившую выполнение?
Информация
- стандарт ISO/IEC C (89/99/11)
- Single UNIX Specifcation, Version 4, 2016 Edition
- The Open Group Base Specifcations Issue 7, 2016 Edition (POSIX.1-2008)
- SEI CERT C Coding Standard
- cправочная информация среды программирования
- справочная информация операционной системы (man pages)
- заголовочные файлы (/usr/include)
- исходные тексты библиотеки (C Standard Library)
Precomp038.exe file information
There are no author’s data about the precomp038.exe process.
Description: Precomp038.exe is not essential for the Windows OS and causes relatively few problems. Precomp038.exe is located in a subfolder of the user’s profile folder or sometimes in a subfolder of Windows folder for temporary files—mostly C:UsersUSERNAMEAppDataLocalTempis-B1D73.tmp.
Known file sizes on Windows 10/11/7 are 328,192 bytes (66% of all occurrences) or 1,291,264 bytes.
The program is not visible. There is no file information. Precomp038.exe is not a Windows system file.
Therefore the technical security rating is 65% dangerous.
Recommended: Identify precomp038.exe related errors
Important: Some malware camouflages itself as precomp038.exe. Therefore, you should check the precomp038.exe process on your PC to see if it is a threat. We recommend Security Task Manager for verifying your computer’s security. This was one of the Top Download Picks of The Washington Post and PC World.
Best practices for resolving precomp038 issues
A clean and tidy computer is the key requirement for avoiding problems with precomp038. This means running a scan for malware, cleaning your hard drive using 1cleanmgr and 2sfc /scannow, 3uninstalling programs that you no longer need, checking for Autostart programs (using 4msconfig) and enabling Windows’ 5Automatic Update. Always remember to perform periodic backups, or at least to set restore points.
Should you experience an actual problem, try to recall the last thing you did, or the last thing you installed before the problem appeared for the first time. Use the 6resmon command to identify the processes that are causing your problem. Even for serious problems, rather than reinstalling Windows, you are better off repairing of your installation or, for Windows 8 and later versions, executing the 7DISM.exe /Online /Cleanup-image /Restorehealth command. This allows you to repair the operating system without losing data.
To help you analyze the precomp038.exe process on your computer, the following programs have proven to be helpful: ASecurity Task Manager displays all running Windows tasks, including embedded hidden processes, such as keyboard and browser monitoring or Autostart entries. A unique security risk rating indicates the likelihood of the process being potential spyware, malware or a Trojan. BMalwarebytes Anti-Malware detects and removes sleeping spyware, adware, Trojans, keyloggers, malware and trackers from your hard drive.
Other processes
fhfshffsf99udau.exe osdtpdetect.exe hcdll2_20_win32.dll precomp038.exe wuala.exe mstwain32.exe frw1.tmp surun.exe p2puimain.exe mouclass.sys tbbs_p.dll [all]
В нашей базе содержится 4 разных файлов с именем precomp038.exe . You can also check most distributed file variants with name precomp038.exe. Совокупная оценка — 5(5) (комментариев: 2).Это исполняемый файл. Вы можете найти его выполняющимся в диспетчере задач как процесс precomp038.exe.
- Продукт:
- (Пустое значение)
- Компания:
- (Пустое значение)
- Описание:
- (Пустое значение)
- Версия:
- (Пустое значение)
- MD5:
- f76c05095ab0188b9cfa8c82089fb00f
- SHA1:
- 54fa38fe4484e307d54d6fa06d728120702dedea
- SHA256:
- 6e3ae0388d3880fe4eee9418d836f7e2ec1a1193657223797cb3bac829fbd04c
- Размер:
- 104448
- Папка:
- %TEMP%is-M853U.tmp
- ОС:
- Windows 7
- Частота:
- Средняя
Процесс «precomp038.exe» безопасный или опасный?
100% файлов помечены как безопасные .
Последний новый вариант файла «precomp038.exe» был обнаружен 4040 дн. назад. В нашей базе содержится 3 шт. вариантов файла «precomp038.exe» с окончательной оценкой Безопасный и ноль вариантов с окончательной оценкой Опасный . Окончательные оценки основаны на комментариях, дате обнаружения, частоте инцидентов и результатах антивирусных проверок.
Комментарии пользователей для «precomp038.exe»
Текущим параметрам фильтрации удовлетворяют несколько файлов. Будут показаны комментарии ко всем файлам.
Комментарии ко всем файлам с именем «precomp038.exe»
-
БЕЗОПАСНЫЙоценка пользователя MiK для файла %TEMP%is-KCHCH.tmpprecomp038.exe
-
БЕЗОПАСНЫЙоценка пользователя chico для файла %TEMP%is-KCHCH.tmpprecomp038.exe
Добавить комментарий для «precomp038.exe»
Для добавления комментария требуется дополнительная информация об этом файле. Если вам известны размер, контрольные суммы md5/sha1/sha256 или другие атрибуты файла, который вы хотите прокомментировать, то вы можете воспользоваться расширенным поиском на главной странице .
Если подробности о файле вам неизвестны, вы можете быстро проверить этот файл с помощью нашей бесплатной утилиты. Загрузить System Explorer.
Проверьте свой ПК с помощью нашей бесплатной программы
System Explorer это наша бесплатная, удостоенная наград программа для быстрой проверки всех работающих процессов с помощью нашей базы данных. Эта программа поможет вам держать систему под контролем. Программа действительно бесплатная, без рекламы и дополнительных включений, она доступна в виде установщика и как переносное приложение. Её рекомендуют много пользователей.
При установке игры доходит до 8.2% и пишет программа»precomp038.exe» не работает.В чем причина кто нибудь подскажит?
Я уже второй раз сталкиваюсь с ней.Первый раз в игре Fallout: New Vegas
Egaliv, это из за установщика в репаке.
PaveL08
Что делать с установщиком подскажишь?
как ее установить подскажите!!лицензия от Акеллы (торрент-едишн)скачивает и ставит стим
а сама игра не ставится
Egaliv- Другой репак качни или у друга попробуй. Может у него поставиться, а ты на флешку перепишешь.
mcbrut
Ну да ладно у меня такая фигня на репаки от Ultra
Купил на http://digital.svyaznoy.ru/ расширенную версию,мне прислали ключ, ввожу его ,а Steam выдаёт «Актевируйте сначала оригинальную игру», что делать?
у мнея подарочьное издание на 1 диске код надо там стереть зашитную полусу но там не хватает слов по 2 диском бумажкак дя потрашителя
и если вести с 1 диска то это 1.5 кода а под потрашителем если ещё вести то слишком много
прастите на 5 раз заработало
Ставьте лицензию через феникса, он ставит без стима.
а как ключ вводить? тут знаков не хватает. помогите кто нибудь.
Такая же проблема,как и у Никиты. Купил лицуху сегодня, при активации в стим 5 окон для ввода кода,а на диске только 3. Кто-нить сталкивался с такой проблемой?
там ещё блин символы не понятные. вводить надо толи 0 толи O, толи 2 толи Z, толи V толи U. хрен поймёшь. тупые дебилы не додумались седлать нормальный код. как терь вводить?
Символы фиг с ними, попробовать можно разобраться,а вот где взять еще 10 цифр кода??
soldatsm сказал что так и надо вводить он просто не правильно ввёл. но я какие варианты только не пробовал у меня не получается ввести правельный. всё время пишет что не тот ключ.
всё ура решил проблема. да так и вводите.
у меня получилось, внимательно еще раз проверяй все символы, а 2 последние строки ввода действительно не нужны…
Ребят,а как перенести сохранения с английской версии на русскую грамотно?переношу,а я на той главе,но никого нет,типа и не проходил,всё закрыто!Что делать?
ilyaaver1993, сохранения находятся по следующему пути -> Dead Island-out (там 2 папки, одна с профилем, другая с сохранениями), кидай их по тому же пути в русскую версию. Если что не пройдено в загруженном сохранении, значит не пройдено.
привет всем каждый раз при установке dead island вылезает ошибка precomp038.exe,я уже не знаю что делать(((
не читается диск пиратский((чё делать?
Скачал лицензию с торентов, без ключа естественно, при установке выдает такую вот тягомутину…………………Support the software companies. If you play this game, BUY iT.Че за не понятная вещь?
Привет всем, помогите пожалуйста, при установке, на 89% пишет: Ошибка извлечения данных из 7z-архива.
Помогите пожалуйста Очень хочю поиграть в эту игру.
Установлена лицензия на ноуте и стационарном компе.
На компе из стима запускается без проблем, а на ноуте пишет «невозможно запустить приложение, попробуйте позже»
А при проверке кэша пишет — 1 файлов не прошли проверку и будут загружены заново.
Пиратка шла нормально.
Переустановка лицухи не помогает…
Уже не знаю что придумать….
У друга на такомже ноуте лицуха работает.
У меня лицензия стим, я устанавливаю стим регюсь, ввожу ключ а дальше пишет что для игры нужно 6.5 гигов а свободно типа 0, места дохера
Купил лицензию DEAD ISLAND (Akella),а установить немогу.Ключ на диске неверен или напечатан не полностью. Присутствует только 15 символов, в то время как в поле ввода требуется 25.Что делать незнаю,впулил деньги коту в очко.Обращался в техподдержку support@akella.com ни ответа ни привета.
Перепробывал все мыслемые и немыслемые варианты с кодом игры,я неслипой. Steam попрежниму пишет , что код недействителен.ЭТО ПОЛНЫЙ РАЗВОД от Akella.Пусть засунут в ж…пу мои 580руб.Х…й я куплю что либо от Akella. Вот тебе и лицензия.
Я через Steam нажимаю установить, а мне пишет, что у меня 0 мегабайт свободного места и надо очистить диск, а у меня там 800 гигов свободно!
СРОЧНО!!! На этапе где показывается сколько нужно памяти для игры у меня пишет типо на моём диске нет места хотя на жёстком диске у меня 833Гб чё делать???
…..Я через Steam нажимаю установить, а мне пишет, что у меня 0 мегабайт свободного места и надо очистить диск, а у меня там 800 гигов свободно!………. Была таже проблема решение такое — в жостком диске на котором ставиш игру создай папку-Program Files , а в ней папку- с названием -Steam ……….чтоб адрес установки игры выглядел к примеру так : D:Program FilesSteam ………ну а дальше …далее ….далее и усё игра нармуль инсталится….
Народ кто мне может ключ с кинуть?)
при авторизации steam зависает !!! помогите !!
при установки игры выдает на 82% возникла ошибка в модуле ISSrepExtract!Что делать ?????
Янер12321
17.09.11 19:04 Я через Steam нажимаю установить, а мне пишет, что у меня 0 мегабайт свободного места и надо очистить диск, а у меня там 800 гигов свободно!
Пропиши Stim в папке установке на английском языке: например DStimи т.д.
Помогите пожалуйста,поставил деад айланд устанавливаться,он установил 1.7 гига из 6,остановился,и далее мне предложили скачать с интернета более 5 гигов.
Вопрос:Так должно быть?Помогите пожалуйста
установил игру. запускаю, пишет (Невозможно осуществить запись в папку с игрой.У вас нет прав на осуществление записи). как это исправить?
dokuchaev1989
Запусти игру с правами администратора.
У мя такая проблема. Карочь я уже играл в Dead Island удалил (чтобы переустановить проблемы были) и устанавливаю. Выдает ошибку что нет файла unins000.dat связано с удалением. Чо творить???!!!
Помогите при установке гдет на половине пишет,что: CreateProcess сбой; код 3
Системе не удается найти указанный путь
Ичто делать хз(((
Люди помогите плиз! Я устанавливаю Dead Island а распаковка доходит до 1000 МВ это примерно 15-16% и усё пишет ошибку, а дальше начинается установка, и игра не запускается. Подскажите что делать?
да да у меня также загрузилось и вот финиш а там написана ошибка запускаю от прав админа и появляется черный экран я ждал по 3 часа и ничего что делать
Дядька_Яр4789
У тебя пиратка ? Пахнет ею.
«установил игру. запускаю, пишет (Невозможно осуществить запись в папку с игрой.У вас нет прав на осуществление записи)»-у меня такая же проблема ладно бы она была токо с одной версией дак я скачал их море и 3-4 установил нифига а самое странное когда хочу удалить ее захожу в панель управления ищу ищу и ничего там нету захожу в пуск там написано удалить dead island попробую с правами адммина
Egaliv
Диск поганенький попался.
Обсуждение этой темы закрыто.
Каждый пользователь компьютера или ноутбука периодически загружает игры или программы из Интернета. Зачастую после этого их необходимо установить, но, к сожалению, это не всегда получается. В статье мы поговорим о том, что за процесс — precomp.exe, как он относится к приложениям и почему может выдавать ошибку при их установке. Прочтите статью полностью, чтобы знать, как решить проблемы, возникшие по вышеуказанной причине.
Precomp.exe — что за процесс?
Разберемся для начала с определением. Программа precomp.exe — это процесс, отвечающий за распаковку или, наоборот, архивацию так называемых прекомпрессорных файлов. Необходим он чаще всего для установки игр из инсталляционного файла. Именно поэтому не стоит удалять или останавливать его, чтобы снизить нагрузку на процессор, в противном случае вы не сможете инсталлировать ни одно приложение на компьютер.
Что делать, если процесс грузит систему?
Мы выяснили, что за процесс — precomp.exe, и почему он важен для системы. Но что делать, если нагрузка на центральный процессор от него идет большая? Первое, что приходит на ум, — завершить или остановить службу, отвечающую за него. Но делать этого не нужно. Здесь стоит разобраться в ситуации. Так, если вы замечаете большую нагрузку при установке игры, то это абсолютно нормально. Проблема же заключается, когда он грузит систему постоянно. В этом случае необходимо проверить, не скачали ли вы вирус на компьютер.
Ошибка: Failed to start precomp.exe
Есть еще одна проблема — ошибка Failed to start precomp.exe. Что делать с ней? Случается она непосредственно при инсталляции приложения. В этом случае установку выполнить невозможно. Исправить ситуацию в большинстве случае также нельзя, так как проблема не в вашей системе, а в самом файле установщика — он неправильно был «собран». Можно порекомендовать загрузить приложение с другого источника.
В некоторых случаях ошибку может вызывать вирус. В этом случае выход есть. О нем мы поговорим ниже.
Как удалить вирус
Мы уже знаем, что за процессом precomp.exe в случае ошибки стоит вирус. В такой ситуации его необходимо немедленно удалить. Делается это следующим образом:
- Установите антивирусную программу Dr.Web CureIt.
- Запустите полное сканирование компьютера.
- По окончанию перезагрузите компьютер.
- Установите программу CCleaner.
- Перейдите в ней в раздел «Реестр».
- Нажмите «Поиск проблем».
- Выделите все найденные проблемы.
- Нажмите «Исправить».
После потребуется снова перезапустить компьютер. Ошибка должна быть устранена.
Заключение
Теперь вы знаете, что за процесс — precomp.exe, и как устранить ошибку, связанную с ним. Главное — остерегаться непроверенных ресурсов, с которых вы скачиваете приложения, ведь именно они могут стать причиной заражения файла.
Process Detail
What is precomp038.exe ?
precomp038.exe is known as IconMan_R and it is developed by Realsil Microelectronics Inc. , it is also developed by . We have seen about 98 different instances of precomp038.exe in different location. So far we haven’t seen any alert about this product. If you think there is a virus or malware with this product, please submit your feedback at the bottom.
Something wrong with precomp038.exe ?
Is precomp038.exe using too much CPU or memory ? It’s probably your file has been infected with a virus. Let try the program named DriverIdentifier to see if it helps.
How to remove precomp038.exe
If you encounter difficulties with precomp038.exe , you can uninstall the associated program (Start > Control Panel > Add/Remove programs
What can you do to fix precomp038.exe ?
Let try to run a system scan with Speed Up My PC to see any error, then you can do some other troubleshooting steps.
If you think this is a driver issue, please try DriverDouble.com
Where do we see precomp038.exe ?
Here is the list of instances that we see for the process: precomp038.exe
Path | Product Name | Vendor | Version | Size | MD5 | |
1 | C:UsersusernameAppDataLocalTempis-6ATPF.tmpprecomp038.exe | IconMan_R | Realsil Microelectronics Inc. | 1.1.9.1 | 129126 | 2424BC5C8A50DC6523AA929146D41DDF |
2 | C:UsersusernameAppDataLocalTempis-J7OSG.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
3 | C:Tempis-DA173.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
4 | C:UsersusernameAppDataLocalTempis-D1SH2.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
5 | C:UsersusernameAppDataLocalTempis-CAP9T.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
6 | C:UsersusernameAppDataLocalTempis-0GAT2.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
7 | D:Tempis-MV6EI.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
8 | C:UsersusernameAppDataLocalTempis-15LQB.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
9 | C:UsersusernameAppDataLocalTempis-R6OJH.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
10 | C:UsersusernameAppDataLocalTempis-GBJAH.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
11 | C:WINDOWSTempis-C6URK.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
12 | C:UsersusernameAppDataLocalTempis-I61EG.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
13 | C:UsersusernameAppDataLocalTempis-R3OK6.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
14 | C:UsersusernameAppDataLocalTempis-52BRH.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
15 | C:UsersusernameAppDataLocalTempis-NHDES.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
16 | C:UsersusernameAppDataLocalTempis-NHDES.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
17 | C:UsersusernameAppDataLocalTempis-A4M5U.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
18 | C:UsersusernameAppDataLocalTempis-R7L7S.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
19 | C:UsersusernameAppDataLocalTempis-KKFBO.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
20 | C:UsersusernameAppDataLocalTempis-TB6PH.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
21 | C:UsersusernameAppDataLocalTempis-9MKJA.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
22 | C:UsersusernameAppDataLocalTempis-PVOGI.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
23 | C:UsersusernameAppDataLocalTempis-82H2N.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
24 | C:UsersusernameAppDataLocalTempis-VN36V.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
25 | C:UsersusernameAppDataLocalTempis-COHJA.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
26 | C:UsersusernameAppDataLocalTempis-DIM42.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
27 | C:UsersusernameAppDataLocalTempis-EJF9M.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
28 | C:UsersusernameAppDataLocalTempis-18MH0.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
29 | C:UsersusernameAppDataLocalTempis-MO0T1.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
30 | C:UsersusernameAppDataLocalTempis-EERHR.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
31 | C:UsersusernameAppDataLocalTempis-5761S.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
32 | C:UsersusernameAppDataLocalTempis-NV89T.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
33 | C:UsersusernameAppDataLocalTempis-MN6QG.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
34 | C:UsersusernameAppDataLocalTempis-OQTN0.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
35 | C:UsersusernameAppDataLocalTempis-UB49C.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
36 | C:UsersusernameAppDataLocalTempis-1GC2L.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
37 | C:UsersusernameAppDataLocalTempis-G0P9G.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
38 | C:UsersusernameAppDataLocalTempis-9MTAP.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
39 | C:UsersusernameAppDataLocalTempis-GNCC3.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
40 | C:UsersusernameAppDataLocalTempis-K5K0F.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
41 | C:UsersusernameAppDataLocalTempis-AO4FS.tmpprecomp038.exe | 10444 | F76C05095AB0188B9CFA8C82089FB00F | |||
42 | C:UsersusernameAppDataLocalTempis-VTCL2.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
43 | C:UsersusernameAppDataLocalTempis-J5CKC.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
44 | C:UsersusernameAppDataLocalTempis-OTFO2.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
45 | C:UsersusernameAppDataLocalTempis-PDUEE.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
46 | C:UsersusernameAppDataLocalTempis-LT75A.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
47 | C:UsersusernameAppDataLocalTempis-HVC4C.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
48 | C:UsersusernameAppDataLocalTempis-RL49G.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
49 | C:UsersusernameAppDataLocalTempis-6IRTH.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
50 | C:UsersusernameAppDataLocalTempis-87O7B.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
51 | C:UsersusernameAppDataLocalTempis-6VJAQ.tmpprecomp038.exe | 38656 | EE241BFC3CB14EE5476C6C7F7D15E77A | |||
52 | C:UsersusernameAppDataLocalTempis-GTHGM.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
53 | C:UsersusernameAppDataLocalTempis-2JLP0.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
54 | C:UsersusernameAppDataLocalTempis-3I2IV.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
55 | C:UsersusernameAppDataLocalTempis-P3UQ4.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
56 | C:UsersusernameAppDataLocalTempis-TD3U9.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
57 | C:UsersusernameAppDataLocalTempis-OABNJ.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
58 | C:UsersusernameAppDataLocalTempis-37BS2.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
59 | C:UsersusernameAppDataLocalTempis-IVH5A.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
60 | C:UsersusernameAppDataLocalTempis-PHDOD.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
61 | C:UsersusernameAppDataLocalTempis-4K3UE.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
62 | C:UsersusernameAppDataLocalTempis-HCD4C.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
63 | C:UsersusernameAppDataLocalTempis-1LGEN.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
64 | D:DOCUME~1AdminLOCALS~1Tempis-6H1OQ.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
65 | C:UsersusernameAppDataLocalTempis-J2709.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
66 | C:UsersusernameAppDataLocalTempis-HO9R3.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
67 | C:UsersusernameAppDataLocalTempis-SHB1H.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
68 | C:UsersusernameAppDataLocalTempis-1KQRJ.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
69 | C:UsersusernameAppDataLocalTempis-QCTJE.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
70 | C:UsersusernameAppDataLocalTempis-QM028.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
71 | C:UsersusernameAppDataLocalTempis-QKQLD.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
72 | C:UsersusernameAppDataLocalTempis-OAE0P.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
73 | C:UsersusernameAppDataLocalTempis-RL9QS.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
74 | C:UsersusernameAppDataLocalTempis-0AU8F.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
75 | C:UsersusernameAppDataLocalTempis-NL33J.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
76 | C:UsersusernameAppDataLocalTempis-F39S6.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
77 | C:UsersusernameAppDataLocalTempis-A2KE9.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
78 | C:UsersusernameAppDataLocalTempis-8LHRO.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
79 | C:UsersusernameAppDataLocalTempis-FOCMB.tmpprecomp038.exe | 32819 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
80 | C:UsersusernameAppDataLocalTempis-DFLNS.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
81 | C:UsersusernameAppDataLocalTempis-G5C0C.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
82 | C:UsersusernameAppDataLocalTempis-66HF9.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
83 | C:UsersusernameAppDataLocalTempis-BV652.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
84 | C:UsersusernameAppDataLocalTempis-P0269.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
85 | C:UsersusernameAppDataLocalTempis-MPNES.tmpprecomp038.exe | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | |||
86 | C:UsersusernameAppDataLocalTempis-DUU7B.tmpprecomp038.exe | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | |||
87 | C:UsersusernameAppDataLocalTempis-JHE9E.tmpprecomp038.exe | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | |||
88 | C:UsersusernameAppDataLocalTempis-95OQ6.tmpprecomp038.exe | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | |||
89 | C:UsersusernameAppDataLocalTempis-GJLTB.tmpprecomp038.exe | 129126 | 2424BC5C8A50DC6523AA929146D41DDF | |||
90 | C:UsersusernameAppDataLocalTempis-NH3IM.tmpprecomp038.exe | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | |||
91 | C:WINDOWSTEMPis-AKKK0.tmpprecomp038.exe | 328192 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
92 | C:UsersusernameAppDataLocalTempis-N853E.tmpprecomp038.exe | = | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | ||
93 | C:DOCUME~1AdminLOCALS~1Tempis-U7S4K.tmpprecomp038.exe | = | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | ||
94 | C:UsersusernameAppDataLocalTempis-U36ER.tmpprecomp038.exe | 328192 | 1D2143DF3600C7A54C12C48AC2D4787F | |||
95 | C:UsersusernameAppDataLocalTempis-D4MC3.tmpprecomp038.exe | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | |||
96 | C:UsersusernameAppDataLocalTempis-T1RHR.tmpprecomp038.exe | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | |||
97 | C:UsersusernameAppDataLocalTempis-UN4TP.tmpprecomp038.exe | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | |||
98 | C:UsersusernameAppDataLocalTempis-L099T.tmpprecomp038.exe | = | 1291264 | 2424BC5C8A50DC6523AA929146D41DDF | ||
Comments about this process:
Sharing your feedback about this process or ask for help
Добрый день, коллеги.
Недавно столкнулся с проблемой, которую никак не могу решить. Задача стоит довольно простая: необходимо создать приложение, которое бы перехватывало стандартный ввод/вывод консольного приложения. Получается: создать приложение, которое бы перехватывало/записывало данные из/в cmd.exe. Не получается: как только пытаюсь запустить любое другое консольное приложение (назовём его example.exe), то при запуске в окне выдаётся ошибка:
«LINES value must be >=2: got 1
initscr(): LINES=1 COLS=1: too small»
Никак не могу понять, в чём может быть проблема. Если запускать example.exe из cmd в винде (а не через Process.Start()), то приложение прекрасно запускается. Также пробовал сначала через Process.Start() запускать cmd, а уже из неё запускать example.exe — выводится та же ошибка.
Привожу код и скриншоты, чтобы было понятней:
C# | ||
|