2015-06-02 22:52:35 +03:00
// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System ;
2015-05-14 22:35:07 +03:00
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Windows.Forms ;
using System.IO ;
namespace VisualPascalABC
{
public partial class WorkbenchRunService : VisualPascalABCPlugins . IWorkbenchRunService
{
void RunnerManager_Exited ( string fileName )
{
if ( System . Threading . Thread . CurrentThread ! = WorkbenchStorage . MainProgramThread )
Workbench . BeginInvoke ( new SetTextDelegate ( RunnerManager_Exited_Sync ) , fileName ) ;
else
RunnerManager_Exited_Sync ( fileName ) ;
}
void RunnerManager_Started ( string fileName )
{
2019-04-26 19:23:32 +03:00
//RunnerManager_Started_Sync(fileName); - ни в коем случае этого не делать! Кнопка Run продолжает оставаться активной!!!
Workbench . BeginInvoke ( new SetTextDelegate ( RunnerManager_Started_Sync ) , fileName ) ;
2015-05-14 22:35:07 +03:00
}
2019-04-20 16:25:39 +03:00
void ButtonsEnableDisable_RunStart ( )
{
Workbench . WidgetController . SetStopEnabled ( true ) ;
Workbench . WidgetController . SetCompilingButtonsEnabled ( false ) ;
Workbench . WidgetController . SetDebugButtonsEnabled ( false ) ;
Workbench . WidgetController . SetOptionsEnabled ( false ) ;
}
void ButtonsEnableDisable_RunStop ( )
{
Workbench . WidgetController . SetStopEnabled ( false ) ;
Workbench . WidgetController . SetCompilingButtonsEnabled ( true ) ;
Workbench . WidgetController . SetDebugButtonsEnabled ( true ) ;
Workbench . WidgetController . SetOptionsEnabled ( true ) ;
}
2015-05-14 22:35:07 +03:00
void RunnerManager_Started_Sync ( string fileName )
{
if ( ! ProjectFactory . Instance . ProjectLoaded )
{
fileName = Tools . FileNameToLower ( fileName ) ;
if ( Tools . FileNameToLower ( Workbench . CurrentEXEFileName ) = = fileName )
{
2019-04-20 16:25:39 +03:00
ButtonsEnableDisable_RunStart ( ) ;
2015-05-14 22:35:07 +03:00
}
RunTabs [ fileName ] . Run = true ;
WorkbenchServiceFactory . DocumentService . SetTabPageText ( RunTabs [ fileName ] ) ;
}
else
{
fileName = Tools . FileNameToLower ( fileName ) ;
2019-04-20 16:25:39 +03:00
ButtonsEnableDisable_RunStart ( ) ;
2015-05-14 22:35:07 +03:00
RunTabs [ fileName ] . Run = true ;
}
}
void RunnerManager_OutputStringReceived ( string fileName , RunManager . StreamType streamType , string text )
{
WorkbenchServiceFactory . OperationsService . AddTextToOutputWindowSync ( fileName , text ) ;
}
void RunnerManager_Exited_Sync ( string fileName )
{
fileName = Tools . FileNameToLower ( fileName ) ;
if ( ! RunTabs . ContainsKey ( fileName ) )
{
2019-04-22 22:25:12 +03:00
string s = "Closing: " + fileName + " \nRunTabs: " ;
2015-05-14 22:35:07 +03:00
foreach ( string ss in RunTabs . Keys )
s + = ss + " " ;
throw new Exception ( s ) ;
}
2019-04-22 22:25:12 +03:00
RunTabs [ fileName ] . Run = false ;
WorkbenchServiceFactory . DocumentService . SetTabPageText ( RunTabs [ fileName ] ) ;
if ( ReadRequests . ContainsKey ( RunTabs [ fileName ] ) )
ReadRequests . Remove ( RunTabs [ fileName ] ) ;
UpdateReadRequest ( false ) ;
WorkbenchServiceFactory . EditorService . SetFocusToEditor ( ) ;
//if (TerminateAllPrograms)
WaitCallback_DeleteEXEAndPDB ( fileName ) ; // сделал всё синхронно - теперь WaitCallback_DeleteEXEAndPDB не должен работать медленно!
//else
// System.Threading.ThreadPool.QueueUserWorkItem(WaitCallback_DeleteEXEAndPDB, fileName); // в потоке - не синхронизировано! Надо запретить запускать что-то до окончания!
2015-05-14 22:35:07 +03:00
if ( ! ProjectFactory . Instance . ProjectLoaded )
{
if ( Tools . FileNameToLower ( WorkbenchServiceFactory . Workbench . CurrentEXEFileName ) = = fileName )
{
2019-04-20 16:25:39 +03:00
ButtonsEnableDisable_RunStop ( ) ;
2015-05-14 22:35:07 +03:00
}
}
else
{
2019-04-20 16:25:39 +03:00
ButtonsEnableDisable_RunStop ( ) ;
2019-05-11 15:24:50 +03:00
} // SSM 22/04/19 - этот код перенесен в конец WaitCallback_DeleteEXEAndPDB - нет, там исключение
2015-05-14 22:35:07 +03:00
}
void RunnerManager_RunnerManagerUnhanledRuntimeException ( string id , string ExceptionType , string ExceptionMessage , string StackTraceData , List < RunManager . StackTraceItem > StackTrace )
{
string localiseMsg = RuntimeExceptionsStringResources . Get ( ExceptionMessage ) ;
WorkbenchServiceFactory . OperationsService . AddTextToOutputWindowSync ( id , string . Format ( Form1StringResources . Get ( "OW_RUNTIME_EXCEPTION{0}_MESSAGE{1}" ) , ExceptionType , localiseMsg ) + Environment . NewLine ) ;
if ( StackTraceData ! = null )
WorkbenchServiceFactory . OperationsService . AddTextToOutputWindowSync ( id , string . Format ( Form1StringResources . Get ( "OW_RUNTIME_EXCEPTION_STACKTRACE{0}" ) , StackTraceData ) + Environment . NewLine ) ;
RunManager . StackTraceItem ToSend = null ;
foreach ( RunManager . StackTraceItem StackTraceItem in StackTrace )
{
if ( StackTraceItem . SourceFileName ! = null )
{
if ( ToSend = = null & & File . Exists ( StackTraceItem . SourceFileName ) )
ToSend = StackTraceItem ;
2016-11-13 12:48:27 +03:00
if ( Workbench . UserOptions . SkipStakTraceItemIfSourceFileInSystemDirectory & &
( Path . GetDirectoryName ( StackTraceItem . SourceFileName ) = = WorkbenchServiceFactory . BuildService . CompilerOptions . SearchDirectory | |
Path . GetDirectoryName ( StackTraceItem . SourceFileName ) = = WorkbenchServiceFactory . BuildService . CompilerOptions . SearchDirectory + "Source" ) )
2015-05-14 22:35:07 +03:00
continue ;
if ( ! ( bool ) Workbench . VisualEnvironmentCompiler . SourceFilesProvider ( StackTraceItem . SourceFileName , PascalABCCompiler . SourceFileOperation . Exists ) )
{
string fn = Path . Combine ( WorkbenchStorage . LibSourceDirectory , Path . GetFileName ( StackTraceItem . SourceFileName ) ) ;
if ( File . Exists ( fn ) )
StackTraceItem . SourceFileName = fn ;
else
continue ;
}
ToSend = StackTraceItem ;
break ;
}
}
if ( ToSend ! = null )
{
List < PascalABCCompiler . Errors . Error > list = new List < PascalABCCompiler . Errors . Error > ( ) ;
list . Add ( new RuntimeException (
string . Format (
Form1StringResources . Get ( "ERRORLIST_RUNTIME_EXCEPTION_MESSAGE{0}" ) ,
localiseMsg . Replace ( Environment . NewLine , " " ) ) ,
ToSend . SourceFileName ,
0 ,
ToSend . LineNumber )
) ;
Workbench . ErrorsListWindow . ShowErrorsSync ( list , true ) ;
if ( RunnerManager . Count > 0 )
{
RunnerManager . KillAll ( ) ;
}
}
}
2019-05-11 15:24:50 +03:00
void WaitCallback_DeleteEXEAndPDB ( object state )
2015-05-14 22:35:07 +03:00
{
2019-04-22 22:25:12 +03:00
//int i = 0;
2019-05-11 15:24:50 +03:00
string fileName = ( string ) state ;
2019-04-22 22:25:12 +03:00
//while (i < 20) // 20 раз пытаться удалять! Это сильно!
//{
try
{
2019-05-11 15:24:50 +03:00
if ( Workbench . UserOptions . DeleteEXEAfterExecute & & File . Exists ( fileName ) )
File . Delete ( fileName ) ;
2019-04-22 22:25:12 +03:00
}
catch
2015-05-14 22:35:07 +03:00
{
2019-04-22 22:25:12 +03:00
WorkbenchServiceFactory . OperationsService . AddTextToCompilerMessagesSync ( "Н е удалось удалить EXE-файл" ) ;
}
try
{
if ( Workbench . UserOptions . DeletePDBAfterExecute )
2015-05-14 22:35:07 +03:00
{
2019-04-22 22:25:12 +03:00
string pdbFileName = Path . ChangeExtension ( fileName , ".pdb" ) ;
if ( File . Exists ( pdbFileName ) )
File . Delete ( pdbFileName ) ;
}
}
catch
{
WorkbenchServiceFactory . OperationsService . AddTextToCompilerMessagesSync ( "Н е удалось удалить PDB-файл" ) ;
}
try
{
if ( RunnerManager . TempBatFiles . ContainsKey ( fileName ) )
2015-05-14 22:35:07 +03:00
{
string batname = RunnerManager . TempBatFiles [ fileName ] ;
if ( File . Exists ( batname ) )
{
File . Delete ( batname ) ;
RunnerManager . TempBatFiles . Remove ( fileName ) ;
}
}
2019-04-22 22:25:12 +03:00
}
catch
{
WorkbenchServiceFactory . OperationsService . AddTextToCompilerMessagesSync ( "Н е удалось удалить bat-файл из словаря RunnerManager.TempBatFiles" ) ;
}
2019-05-11 15:24:50 +03:00
// SSM 22/04/19 - этот код перенесён сюда из RunnerManager_Exited_Sync - нет, тут исключение!
/ * if ( ! ProjectFactory . Instance . ProjectLoaded )
{
if ( Tools . FileNameToLower ( WorkbenchServiceFactory . Workbench . CurrentEXEFileName ) = = fileName )
{
ButtonsEnableDisable_RunStop ( ) ;
}
}
else
{
ButtonsEnableDisable_RunStop ( ) ;
} * /
2019-04-22 22:25:12 +03:00
//return;
//System.Threading.Thread.Sleep(20);
//i++;
//}
2015-05-14 22:35:07 +03:00
}
void ReadStringRequest ( string ForId )
{
ForId = Tools . FileNameToLower ( ForId ) ;
if ( ! ReadRequests . ContainsKey ( RunTabs [ ForId ] ) )
{
if ( WorkbenchServiceFactory . DebuggerManager . IsRun ( ForId ) & & WorkbenchServiceFactory . DebuggerManager . CurPage ! = null )
ReadRequests . Add ( WorkbenchServiceFactory . DebuggerManager . CurPage , "" ) ;
else
ReadRequests . Add ( RunTabs [ ForId ] , "" ) ;
}
Workbench . BeginInvoke ( new ReadStringRequestSyncDel ( ReadStringRequestSync ) ) ;
}
delegate void ReadStringRequestSyncDel ( ) ;
void ReadStringRequestSync ( )
{
UpdateReadRequest ( false ) ;
}
public void UpdateReadRequest ( bool changeSelected )
{
if ( changeSelected & & Workbench . OutputWindow . InputPanelVisible )
{
ReadRequests [ WorkbenchServiceFactory . DocumentService . LastSelectedTab ] = Workbench . OutputWindow . InputTextBoxText ;
}
if ( ReadRequests . ContainsKey ( WorkbenchServiceFactory . DocumentService . CurrentCodeFileDocument ) )
{
Workbench . OutputWindow . InputTextBoxText = ReadRequests [ WorkbenchServiceFactory . DocumentService . CurrentCodeFileDocument ] ;
Workbench . OutputWindow . InputPanelVisible = true ;
Workbench . OutputWindow . InputTextBoxCursorToEnd ( ) ;
return ;
}
Workbench . OutputWindow . InputPanelVisible = false ;
}
bool IsOneProgramStarted ( )
{
int num = 0 ;
foreach ( VisualPascalABCPlugins . ICodeFileDocument doc in RunTabs . Values )
if ( doc . Run )
num + + ;
return num = = 1 ;
}
}
}