fbpx
Welcome, Guest
Username: Password: Remember me
Please use this forum for suggestions to the XSharp Development Team
  • Page:
  • 1
  • 2

TOPIC: Possibly error message when starting program with missing included DLL

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13761

  ArneOrtlinghaus's Avatar Topic Author ArneOrtlinghaus Offline Posts: 161
I had now the case, that an EXE program did not start because of a missing DLL. The program started and stopped without a message. In the event log I found the following entry:
System.IO.FileNotFoundException
bei <Module>.$AppInit()
bei RadixDN.Exe.Functions.Start()

I looked into $AppInit() with ILSpy and I saw an exception handling. Is it probably possible that in case of an EXE file you open a windows message box with the exception? When having Win32-programs with a missing DLL normally the Runtime shows such a message.
Thanks
Arne

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13762

  wriedmann's Avatar wriedmann Away Posts: 2206
Hi Arne,
that is a problem I had several times, but I don't thing the devteam can do anything here as it is the .NET Runtime that loads the DLLs.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13763

  wriedmann's Avatar wriedmann Away Posts: 2206
Hi Arne,
I have looked better - maybe there couid be a solution:
social.msdn.microsoft.com/Forums/office/...s-dll-file?forum=wpf
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13765

  robert's Avatar robert Offline Posts: 1542
Arne,

Adding a message box should be possible, however that will add a dependency to System.Windows.Forms to all apps. Or we need to add a _DLL FUNCTION in the generated code for MessageBox in user32.dll.
And that would make our programs incompatible with non windows platforms...


Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13767

  wriedmann's Avatar wriedmann Away Posts: 2206
Hi Robert,
and write an error log?
I suspect this check must be executed before any user code is executed, so there is no possibility to register a handler.... Or would it be possible to call a function with a fixed name in the exe, when it exist?
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13768

  robert's Avatar robert Offline Posts: 1542
Wolfgang,

I think that calling a function in the EXE should be possible, as long as that function does not depend on any of the initializers that are called from $AppInit() ( init procedures).
I could pass the exception object to that function.
Do you have a suggestion for a function name ?

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13769

  mainhatten's Avatar mainhatten Offline Posts: 108

wriedmann wrote: I have looked better - maybe there couid be a solution:
social.msdn.microsoft.com/Forums/office/...s-dll-file?forum=wpf


If Arne has a similar customer-PEBCAC problem as the original poster of the linked thread, another option is to rename the .exe
Whatever_StartOptimized.exe
and to add another program (depending on nothing but itself, perhaps a JSON or dbf data store and perhaps the GAC) first verifying all dll are in expected place and fit expected CRC-value, either showing nice error msg or starting "Whatever_StartOptimized.exe" if all is ok.

Sometimes going the long way is easier than to confront PEBCAC customers head on...

regards
thomas

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13770

  wriedmann's Avatar wriedmann Away Posts: 2206
Hi Robert,
that would be great, thank you!
As function name I could suggest "XSharpInitError()", but I'm not really good inventing names <g>.
The important thing is that a sample for such a funtion would be added by XPorter and also in the sample applications in both XIDE and VS, so people sees it and uses it also in own applications.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13771

  Karl-Heinz's Avatar Karl-Heinz Offline Posts: 521
Guys
,
i think the first question should be how Arne is currently catching exceptions ? Is he really using a WPF app, where it seems there is a catch problem when i follow Wolfgang´s link ?

i´m using a global Exception handler, and til now i see all errors using the X# buildin ErrorDialog. Maybe Arne can give a sample when exactely such a exception handling fails ?
[STAThread];
FUNCTION Start() AS INT 
LOCAL oDlg AS ErrorDialog 
LOCAL oXApp AS XApp

	TRY
		oXApp := XApp{}
		oXApp:Start() 
				  
	CATCH e AS Exception 
		oDlg := ErrorDialog { e }
		oDlg:showDialog() 
		
	END TRY
	
RETURN 0  


CLASS XApp INHERIT App

METHOD Start() 

.. open the first Window 

RETURN 0

END CLASS 

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13772

  Karl-Heinz's Avatar Karl-Heinz Offline Posts: 521
Hi Arne

Would be interesting to know. When you add this init proc to your app do you see the debout() content before your app closes ?
PROCEDURE AppInit1 _INIT1
	
	DebOut( "AppInit1" )
	
	RETURN NIL

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13775

  ArneOrtlinghaus's Avatar Topic Author ArneOrtlinghaus Offline Posts: 161
Hi all,
thank you for responding.
I understand that a messagebox in general can disturb usage of different GUIs. Having the possibility for a callback function for trapping such an error could be a solution. The name Wolfgang proposed would be ok.
Of course normally it should not happen, that a Dll is missing and in the last years at our customer sites this happens only randomly. Possible reasons can be for example an Antivirus, that blocks reading, copying files or deletes them (or an admin that tries to clean an infected fileserver). For this case such an error message simplifies diagnose time. Unfortunately the event log entry currently does not give an indication which file could have generated the exception. Using Process Monitor from Sysinternals showed the missing file, but it takes much time using such a tool and analyzing it.

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13777

  robert's Avatar robert Offline Posts: 1542
Guys,
I have given this some thought and a special function name will not be the way to go.
This function will become part of the compiler generated static functions class and that means that the static constructor for this class will have to be called before the code in the special function can be executed. This static constructor contains code to initialize defines that do not have a compile time constant (such as defines that have a symbol as value, eg DEFINE SomeValue := #SomeSymbol) and the code to initialize globals that are declared with an initializer (GLOBAL aValues[0] AS ARRAY).
There is a big risk that some of this initialization code will depend on external DLLs that may or may not be correctly initialized.

However there is a better way to do this and it is already built into the compiler.
This is the compiler option -Main.

Consider the following code:
GLOBAL x AS INT
GLOBAL y := 1 / x AS INT
   
FUNCTION Start AS VOID
	? "Function Start"
    RETURN

This code will generate an exception at startup:

Unhandled Exception: System.TypeInitializationException: The type initializer for 'Application1.Exe.Functions' threw an exception. ---> System.DivideByZeroException: Attempted to divide by zero.
at Application1.Exe.Functions..cctor() in C:\XIDE\Projects\Default\Applications\Application1\Prg\Start.prg:line 4
--- End of inner exception stack trace ---
at Application1.Exe.Functions.Start()

And you cannot intercept this.

Now add the following code:
CLASS MyStartupCode
	STATIC METHOD Start AS VOID  
		TRY
                        // Note that in the following line the name before .Exe must 
                        // match the file name of your EXE. In my case I am generating Application1.exe
			Application1.Exe.Functions.Start()
		CATCH e AS Exception   
                // We should probably log this to disk as well !
 		Console.WriteLine("An unhandled exception has occurred")
		Console.WriteLine("===================================")
		DO WHILE e != NULL         
			Console.WriteLine("Exception: "+e:Message)                             
			Console.WriteLine("Callstack:")
			Console.WriteLine(e:StackTrace)
			Console.WriteLine()
			e := e:InnerException
		ENDDO             
		Console.WriteLine("===================================")
		Console.WriteLine("Press any to close the application")
		Console.ReadLine()				
               END TRY
		RETURN		
END CLASS

You may have to change the call to Application1.Exe.Functions.Start() into something that matches your EXE name.
Now goto the General page in the application properties in VS and at the entry "Startup Object" set the value MyStartupCode (in XIDE add the command line option -main:MyStartupCode)

and run the code again

Of course you can also register an UnHandledException handler in the AppDomain class inside the new startup code. Change the code to:
CLASS MyStartupCode
	STATIC METHOD Start AS VOID           
		TRY
			System.AppDomain.CurrentDomain:UnhandledException += ExceptionHandler
			Application1.Exe.Functions.Start()
		CATCH e AS Exception
			ExceptionHandler(NULL, UnhandledExceptionEventArgs{e, TRUE})
		END TRY
		RETURN		
	STATIC METHOD ExceptionHandler( sender AS OBJECT, args AS UnhandledExceptionEventArgs) AS VOID
		LOCAL e AS Exception
		e := (Exception) args:ExceptionObject
               // We should probably log this to disk as well !
		Console.WriteLine("An unhandled exception has occurred")
		Console.WriteLine("===================================")
		DO WHILE e != NULL 
		        Console.WriteLine("Exception: "+e:Message) 
			Console.WriteLine("Callstack:")
		        Console.WriteLine(e:StackTrace)
			Console.WriteLine()
			e := e:InnerException
		ENDDO             
		Console.WriteLine("===================================")
		Console.WriteLine("Press any to close the application")
		Console.ReadLine()				
				
END CLASS

One remark:
Do NOT use or call any Xbase types and or functions in the exception handler, since you can't be sure that the runtime was initialized properly. If you use classes written by yourself make sure that everything is strongly typed and uses native types only. So no USUAL, FLOAT, SYMBOL etc.

I hope this helps.

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

Last edit: by robert.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13778

  wriedmann's Avatar wriedmann Away Posts: 2206
Hi Robert,
thank you very much - this is great!
I will build a sample later today.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13779

  ArneOrtlinghaus's Avatar Topic Author ArneOrtlinghaus Offline Posts: 161
Great, it works as I have hoped and this without having to wait for updates, thank you!
I had to modify the code a little bit as below (adding the word strict and using a message box, because the console window did not appear on the screen.


CLASS MyStartupCode
STATIC METHOD Start AS VOID strict
local c as string
TRY
// Note that in the following line the name before .Exe must
// match the file name of your EXE. In my case I am generating Application1.exe
radixdn.exe.Functions.Start()
CATCH e AS Exception

c := "An unhandled exception has occurred"+crlf
c += "==================================="+crlf
DO WHILE e != NULL
c += "Exception: "+e:Message+crlf
c += "Callstack:"+crlf
c += e:StackTrace+crlf
e := e:InnerException
ENDDO
c += "==================================="+crlf

MessageBox (null_ptr,string2psz(c), string2psz("RADIX"), MB_OK + MB_ICONSTOP+ MB_DEFAULT_DESKTOP_ONLY + MB_TOPMOST)
// We should probably log this to disk as well !
END TRY
RETURN
END CLASS
Attachments:

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 4 days ago #13780

  wriedmann's Avatar wriedmann Away Posts: 2206
Hi Arne,
if you like to open a console window from a non-console application (WPF, Windows Forms, VO GUI) you need that here:
stackoverflow.com/questions/4362111/how-...-a-forms-application
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 3 days ago #13781

  robert's Avatar robert Offline Posts: 1542
Arne,

Adding Strict() is needed because you have enabled the compiler option /vo5 (implicit Clipper calling convention).
My sample did not have that.

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 3 days ago #13782

  robert's Avatar robert Offline Posts: 1542
Arne,

One more thing:
you are using String2Psz() in your exception handler.
I would not recommend that, since this relies on the runtime and this will fail when one of the X# runtime DLLs is missing.
To avoid that declare MessageBox yourself without PSZ type and add it as method to your MyStartupCode class
// add this line to the start of your PRG
USING System.Runtime.InteropServices
// add this to your MyStartupCode class
[DllImport("user32.dll", CharSet := CharSet.Ansi)];
STATIC METHOD MessageBox(hwnd AS IntPtr, lpText AS STRING, lpCaption AS STRING, uType AS DWORD) AS INT PASCAL

Do not make this a function, because that will again fail when the type initializer of the Functions class fails...



Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 3 days ago #13790

  ArneOrtlinghaus's Avatar Topic Author ArneOrtlinghaus Offline Posts: 161
Robert,
this is something interesting, which I do not understand, why it can work.
The MessageBox in user32 surely is the C-base function with pointers to 0-terminated C-Strings. Here you declare the parameters using the Dotnet-Variable type "STRING" which is an object. Who cares for the conversion of this object when even with this interface you give the compiler hints that seem not to fit?
STATIC METHOD MessageBox(hwnd AS IntPtr, lpText AS STRING, lpCaption AS STRING, uType AS DWORD) AS INT PASCAL
int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 3 days ago #13792

  robert's Avatar robert Offline Posts: 1542
Arne,

The method is marked with the [DllImport] attribute. This tells the runtime that it is a native DLL.
The runtime "knows" that it needs to do some work on the strings.
The CharSet := CharSet.Ansi tells the .Net runtime that the managed strings need to be converted from Unicode to Ansi.
This is all managed "magically" by the .Net runtime.
You can also control this behavior by using a MarshalAs attribute
You could therefore also write

[DllImport("user32.dll"];
STATIC METHOD MessageBox(hwnd AS IntPtr, [MarshalAs(UnmanagedType.LPStr)] lpText AS STRING, [MarshalAs(UnmanagedType.LPStr)] lpCaption AS STRING, uType AS DWORD) AS INT PASCAL

LIkewise you can also pass a stringbuilder to methods in the win32 api that return strings (such as GetWindowText)
See docs.microsoft.com/en-us/dotnet/framewor...rshaling-for-strings

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

Possibly error message when starting program with missing included DLL 2 weeks 3 days ago #13798

  ArneOrtlinghaus's Avatar Topic Author ArneOrtlinghaus Offline Posts: 161
If someone needs the [STAThread] attribute for Internet Explorer control/Olecontrols, it is important to position it before the first method called, in this case the new Start method and not the start function.
CLASS MyStartupCode
[STAThread] ;
STATIC METHOD Start AS VOID strict

Please Log in or Create an account to join the conversation.

  • Page:
  • 1
  • 2