This forum uses cookies. Click X button to hide this message. What is stored? / Privacy
Total Commander Forum Index Total Commander
Forum - Public Discussion and Support
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Meaningful error message when program start fails
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Total Commander Forum Index -> TC suggestions (English) Printable version
View previous topic :: View next topic  
Author Message
Dalai
Power Member
Power Member


Joined: 28 Jan 2005
Posts: 6086
Location: Meiningen (Südthüringen)

PostPosted: Sat Jun 17, 2017 3:38 pm    Post subject: Meaningful error message when program start fails Reply with quote

Hi,

This recent thread reminded me again that TC doesn't show a meaningful error message when the launch of an executable fails. One has to start the program again via context menu to make Explorer execute this program to learn the reason why the program launch failed. This is really annoying!

Please make TC show a meaningful error when a program fails to start. In Delphi there's even a group of functions that can help to do so. I use something like this:
Code:
MessageBox(Self.Handle, PChar(SysErrorMessage(GetLastError)), PLUGINNAME, MB_OK or MB_ICONHAND);
This makes the system translate the error code into an error message and also translates this to the current OS language, so there's no need to change TC's language files.

I'm not sure whether or not Delphi 2 has SysErrorMessage function, but I'm sure that there's a way to deal with that if that's the case. Of course instead of GetLastError you could use any other approriate variable, e.g. the return code of a function or something. Maybe even RaiseLastOsError/RaiseLastWin32Error could help in this situation.

Regards
Dalai
_________________
#101164 Personal licence
Athlon X4 880K, 16 GiB RAM, Gigabyte F2A88X-D3HP, Win7 x64

Plugins: Services2, Startups
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35974
Location: Switzerland

PostPosted: Tue Jun 20, 2017 3:09 am    Post subject: Reply with quote

It doesn't but there seems to be a Windows function:
FormatMessage

The only problem would be that the message language would differ from the language chosen within Total Commander. Maybe I will show a combined error (the one I show now and the windows error).
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Dalai
Power Member
Power Member


Joined: 28 Jan 2005
Posts: 6086
Location: Meiningen (Südthüringen)

PostPosted: Tue Jun 20, 2017 6:22 am    Post subject: Reply with quote

ghisler(Author) wrote:
It doesn't but there seems to be a Windows function:
FormatMessage

Yes, that's the one that SysErrorMessage uses, too.

Quote:
The only problem would be that the message language would differ from the language chosen within Total Commander.

Well, that's better than it is now, isn't it? No matter which language the current "Access denied" message is shown, it's meaningless. As I see it, FormatMessage has a dwLanguageId parameter which might help with that.

Quote:
Maybe I will show a combined error (the one I show now and the windows error).

Yes, that could be a solution, too.

Regards
Dalai
_________________
#101164 Personal licence
Athlon X4 880K, 16 GiB RAM, Gigabyte F2A88X-D3HP, Win7 x64

Plugins: Services2, Startups
Back to top
View user's profile Send private message Send e-mail
Dalai
Power Member
Power Member


Joined: 28 Jan 2005
Posts: 6086
Location: Meiningen (Südthüringen)

PostPosted: Sun Dec 31, 2017 9:42 am    Post subject: Reply with quote

Thanks for implementing this. Unfortunately I don't know if it really works. I just did the following: Downloaded FB-Traffic and tried to start it on a Windows XP system in TC 9.12. TC just said
Code:
---------------------------
Total Commander
---------------------------
Zugriff verweigert!
---------------------------
OK   
---------------------------

(which translates to "Access denied") which is just as meaningless as before. Changing TC's language to English just adds the translation to the message which then reads
Code:
---------------------------
Total Commander
---------------------------
Access denied!

"Zugriff verweigert"
---------------------------
OK   
---------------------------


Launching the EXE via context menu tells me the real reason:
Code:
---------------------------
C:\FB-Traffic\FB-Traffic.exe
---------------------------
C:\FB-Traffic\FB-Traffic.exe ist keine zulässige Win32-Anwendung.

---------------------------
OK   
---------------------------
(FB-Traffic.exe is not a valid Win32 application).

How come TC doesn't tell as much? You can try this yourself with FB-Traffic on XP, even if you don't have a Fritz!Box since the program doesn't run on XP anyway (which I was trying to find out).

Regards
Dalai
_________________
#101164 Personal licence
Athlon X4 880K, 16 GiB RAM, Gigabyte F2A88X-D3HP, Win7 x64

Plugins: Services2, Startups
Back to top
View user's profile Send private message Send e-mail
Dalai
Power Member
Power Member


Joined: 28 Jan 2005
Posts: 6086
Location: Meiningen (Südthüringen)

PostPosted: Mon Jan 01, 2018 9:34 am    Post subject: Reply with quote

Out of curiosity, I made a quick and dirty implementation of a small Delphi program to find out whether or not I can get the reason from the OS. Turns out: in Delphi 5 calling SysErrorMessage() function returns just an empty string while RaiseLastWin32Error() tells at least the error code 193, but also with an empty string for the message Sad. In Delphi XE2 SysErrorMessage() returns the real reason:
Code:
---------------------------
Project1
---------------------------
%1 ist keine zulässige Win32-Anwendung.
---------------------------
OK   
---------------------------
(%1 is not a valid Win32 application). Then, I copied the SysErrorMessage() function from XE2 to Delphi 5, renamed it to avoid confusion and voilà, I got the error message string Smile. Next, I dug a little deeper to find out why this is, and it turns out that specifying FORMAT_MESSAGE_IGNORE_INSERTS flag in FormatMessage() function call makes the difference. If the flag is not specified, the returned string is empty. If the flag is set, the message is OK. Note the literal %1 in the returned message.

Conclusion: Please add FORMAT_MESSAGE_IGNORE_INSERTS flag to the FormatMessage() call. It might be a good idea to replace the %1 in the message (or let the FormatMessage() do it, but I don't know how that would work). Also, please add the error code to the message TC shows when something fails, so the user at least has the option to look up the error code to see what the system was trying to tell.

Regards
Dalai
_________________
#101164 Personal licence
Athlon X4 880K, 16 GiB RAM, Gigabyte F2A88X-D3HP, Win7 x64

Plugins: Services2, Startups
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35974
Location: Switzerland

PostPosted: Thu Jan 04, 2018 5:37 am    Post subject: Reply with quote

Thanks for the analysis! I didn't know about that parameter.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Dalai
Power Member
Power Member


Joined: 28 Jan 2005
Posts: 6086
Location: Meiningen (Südthüringen)

PostPosted: Wed May 23, 2018 11:41 am    Post subject: Reply with quote

It looks like TC 9.20 still behaves the same. Any chance this flag gets added to TC 9.20 before its final release? This might also help with SmartScreen mentioned in this thread (although I'm totally unsure about this).

Regards
Dalai
_________________
#101164 Personal licence
Athlon X4 880K, 16 GiB RAM, Gigabyte F2A88X-D3HP, Win7 x64

Plugins: Services2, Startups
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35974
Location: Switzerland

PostPosted: Thu May 24, 2018 3:41 am    Post subject: Reply with quote

OK, I will add it to beta 5.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
MarcinW
Power Member
Power Member


Joined: 23 Jan 2012
Posts: 852
Location: Poland

PostPosted: Thu May 24, 2018 9:30 am    Post subject: Reply with quote

I just found some description of the problem with ERROR_BAD_EXE_FORMAT / FORMAT_MESSAGE_IGNORE_INSERTS here: https://blogs.msdn.microsoft.com/oldnewthing/20071128-00/?p=24353

Regards
Back to top
View user's profile Send private message Send e-mail
Dalai
Power Member
Power Member


Joined: 28 Jan 2005
Posts: 6086
Location: Meiningen (Südthüringen)

PostPosted: Wed May 30, 2018 11:41 am    Post subject: Reply with quote

Although history.txt claims that the flag is set in TC 9.20 beta5, I still only get "Access denied" when trying to start FB-Traffic on XP, while my test program shows the error message "%1 is not a valid Win32 application". Don't know what's different/wrong in TC but I hope you can take a look at it.

Here's my test program:
Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ShellAPI;

type
  TForm1 = class(TForm)
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function MySysErrorMessage(ErrorCode: Cardinal): string;
var
  Buffer: PChar;
  Len: Integer;
begin
  Len := FormatMessage(
    FORMAT_MESSAGE_FROM_SYSTEM or
    FORMAT_MESSAGE_IGNORE_INSERTS or
    FORMAT_MESSAGE_ARGUMENT_ARRAY or
    FORMAT_MESSAGE_ALLOCATE_BUFFER, nil, ErrorCode, 0, @Buffer, 0, nil);

  try
    while (Len > 0) and (Buffer[Len - 1] in [#0..#32, '.']) do Dec(Len);
    SetString(Result, Buffer, Len);
  finally
    LocalFree(HLOCAL(Buffer));
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var a: TShellExecuteInfo;
    b: DWORD;
begin
    if OpenDialog1.Execute then begin
        ZeroMemory(@a, SizeOf(a));
//        a.Wnd:= Self.Handle;
        a.fMask:= SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI;
        a.lpFile:= PChar(OpenDialog1.FileName);
        a.cbSize:= SizeOf(TShellExecuteInfo);
        if NOT ShellExecuteEx(@a) then begin
            b:= GetLastError;
//            RaiseLastWin32Error;
            raise Exception.Create(MySysErrorMessage(b));
        end;
    end;
end;

end.

_________________
#101164 Personal licence
Athlon X4 880K, 16 GiB RAM, Gigabyte F2A88X-D3HP, Win7 x64

Plugins: Services2, Startups
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35974
Location: Switzerland

PostPosted: Thu May 31, 2018 3:01 am    Post subject: Reply with quote

I'm setting the following parameters:
FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or
FORMAT_MESSAGE_ARGUMENT_ARRAY
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Dalai
Power Member
Power Member


Joined: 28 Jan 2005
Posts: 6086
Location: Meiningen (Südthüringen)

PostPosted: Thu May 31, 2018 9:25 am    Post subject: Reply with quote

So the flag FORMAT_MESSAGE_ALLOCATE_BUFFER isn't used in TC. As per my tests, it doesn't matter if you manage the buffer yourself or leave that to Windows. The following code works fine too, meaning I get the error message:
Code:
function MySysErrorMessage(ErrorCode: Cardinal): string;
var
  Buffer: array[0..8191] of Char;
  Len, Lsize: Integer;
begin
  Lsize:= SizeOf(Buffer) * SizeOf(Char) - 1;
  ZeroMemory(@Buffer, Lsize);
  Len := FormatMessage(
    FORMAT_MESSAGE_FROM_SYSTEM or
    FORMAT_MESSAGE_IGNORE_INSERTS or
    FORMAT_MESSAGE_ARGUMENT_ARRAY, nil, ErrorCode, 0, @Buffer, Lsize, nil);

  try
    while (Len > 0) and (Buffer[Len - 1] in [#0..#32, '.']) do Dec(Len);
    SetString(Result, Buffer, Len);
  finally
  end;
end;
Conclusion: Something else must be wrong. I don't know what else I could test Neutral - if you do, please let me know.

Regards
Dalai
_________________
#101164 Personal licence
Athlon X4 880K, 16 GiB RAM, Gigabyte F2A88X-D3HP, Win7 x64

Plugins: Services2, Startups
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35974
Location: Switzerland

PostPosted: Fri Jun 01, 2018 8:23 am    Post subject: Reply with quote

What error text do you get? I use a buffer length of 256 characters, maybe it's too short?
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Dalai
Power Member
Power Member


Joined: 28 Jan 2005
Posts: 6086
Location: Meiningen (Südthüringen)

PostPosted: Fri Jun 01, 2018 8:40 am    Post subject: Reply with quote

ghisler(Author) wrote:
What error text do you get?

Code:
%1 ist eine unzulässige Win32-Anwendung
(%1 is not a valid Win32 application) The length returned by FormatMessage is 41 in my case, so your buffer of 256 characters should be enough for this message. But I'm pretty sure there are much longer error texts in Windows, so I think it's a good idea to use a larger buffer.

Do you get this text with the FormatMessage function? Do you have some executable that you can test with to get this error text? If you can debug on XP, use the linked FB-Traffic mentioned and linked above; it doesn't run on XP so it's a perfect candidate to provoke this error message.

Regards
Dalai
_________________
#101164 Personal licence
Athlon X4 880K, 16 GiB RAM, Gigabyte F2A88X-D3HP, Win7 x64

Plugins: Services2, Startups
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35974
Location: Switzerland

PostPosted: Sun Jun 03, 2018 4:25 am    Post subject: Reply with quote

Maybe it's because I'm no longer showing my own error dialog when launching EXE files on Windows 10 fall creators update or newer? I had to switch to the Windows error dialog, because otherwise nothing would happen for files caught in Windows smart screen.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> TC suggestions (English) All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Imprint/Impressum: This site is maintained by Ghisler Software GmbH
Privacy Policy | Datenschutzerklärung | Politique de Confidentialité

Using phpBB © phpBB Group