Visual C++ проект работает нормально через VStudio, но из Explorer умирает после появления в панели уведомлений
Я просто изменил свой проект C++/CLI, чтобы изменить способ синтаксического анализа его текстового файла config.ini. Но он по-прежнему обращается к файлу на диске, как и раньше:
StreamReader ^sr = gcnew StreamReader(CONFFILE_NAME);
String ^rdfl = sr->ReadToEnd();
sr->Close();
Теперь он не будет работать вне среды VS2008Express. Это WinForm, притворяющийся сервисом и должен оставаться в трее уведомлений, но вместо этого он просто мигает там значком по умолчанию, пока я не наведу на него мышь, верный признак того, что он уже ненормально завершился. Кстати, значок по умолчанию должен быть немедленно обновлен, поэтому я еще раз проверю этот момент. Я только что попробовал очистить и восстановить.
Благодарю.
_РЕДАКТИРОВАТЬ_
Он работает нормально, если файл конфигурации отсутствует или несовместим - появляется окно, и я ввожу правильную конфигурацию, и она выключается. Но он перезагружает данные конфигурации из файла из VS2008 и раньше извне (хотя с большой логической ошибкой в кодировании).
Вот код, следующий сразу за тем, что выложен выше:
int fore = 0;
int aft;
while (statsRead < 4) {
fore = rdfl->IndexOf(':', aft)+1;
if (fore == -1) break;
aft = rdfl->IndexOf('\n', fore);
if (aft == -1) break;
if (statsRead == 0) str1 = rdfl->Substring(fore, aft-fore)->Trim();
else if (statsRead == 1) str2 = rdfl->Substring(fore, aft-fore)->Trim();
else {
String ^tmpIntStr = rdfl->Substring(fore, aft-fore)->Trim();
int tmp_int;
if (Int32::TryParse(tmpIntStr, tmp_int)) {
switch (statsRead) {
case 2: int1 = tmp_int; break;
case 3: int2 = tmp_int; break;
}
} else break;
}
++statsRead;
}
}
после этого любой оставшейся статистике присваиваются значения по умолчанию, которые работают в моем случае, кроме первого, которое вызывает окно.
_РЕДАКТИРОВАТЬ_
Я обновил вышеупомянутое с помощью блоков try и catch в соответствии с рекомендациями Hans, а также MSDN literatur для StreamReader, но все равно он не работает, трассировка стека (спасибо, Hans) указывает, что моя ошибка while
заявление (нет, спасибо, мс)
if (File::Exists(CONFFILE_NAME)) {
String ^rdfl;
try {
StreamReader ^sr = gcnew StreamReader(CONFFILE_NAME);
try{
rdfl = sr->ReadToEnd();
} finally {
if ( sr )
delete (IDisposable^)sr;
}
} catch (Exception ^ex) {
MessageBox::Show(ex->Message);
}
int fore = 0;
int aft;
while (statsRead < 4) {
fore = rdfl->IndexOf(':', aft)+1;
if (fore == -1) break;
aft = rdfl->IndexOf('\n', fore);
if (aft == -1) break;
if (statsRead == 0) str1 = rdfl->Substring(fore, aft-fore)->Trim();
else if (statsRead == 1) str2 = rdfl->Substring(fore, aft-fore)->Trim();
else {
String ^tmpIntStr = rdfl->Substring(fore, aft-fore)->Trim();
int tmp_int;
if (Int32::TryParse(tmpIntStr, tmp_int)) {
switch (statsRead) {
case 2: int1 = tmp_int; break;
case 3: int2 = tmp_int; break;
}
} else break;
}
++statsRead;
}
}
1 ответ
Обычно это простая ошибка, например, CONFFILE_NAME не является полным именем пути, а рабочий каталог по умолчанию не указан там, где вы надеетесь. Фокус на подключении отладчика. Это легко сделать в.NET, например, используйте System::Diagnostics::Debugger::Launch() в вашем методе Main(). И напишите обработчик событий для AppDomain::CurrentDomain->UnhandledException, чтобы исключения не попадали в разрядный сегмент без уведомления. Обязательно удалите операторы try/catch, которых там быть не должно.