-
Content Count
3019 -
Joined
-
Last visited
-
Days Won
108
Everything posted by dummzeuch
-
Yes, but the problem I reported still happened in 12.2. That's why I created a workaround when I started using Delphi 12(.2) in earnest.
-
Is a missing close button normal for IDE windows in Delphi 12?
dummzeuch replied to dummzeuch's topic in Delphi IDE and APIs
I am sure it has been like this from the first Delphi 12 installation which of course was "vanilla" back then. But since I just realized it might be a bug I have not yet tried to reproduce it. Knowing my luck, it might be yet another effect of using two screens in a peculiar setup that's apparently unique on planet earth. -
executing a command with ssh-pascal runs into timeout
dummzeuch posted a topic in Network, Cloud and Web
I am using ISshExec.Exec from @pyscripter's ssh-pascal library for running a command that calculates checksums on all files in a directory tree. Since this is potentially a large tree and some of the files are huge, this takes quite a while. Unfortunately Exec is synchronously waiting for the output of the command which creates two issues: My program has to wait for the command to finish before it can get any output. For the huge files calculating the checksum takes longer than the standard timeout which raises an exception in the Exec method (actually in ReadStringFromChannel) and stops reading (the command continues running though) Is there any existing way to get the output asynchronously? EDIT: I just found that my ssh-pascal library was outdated, in particular the reading code has changed significantly. Maybe my second point has become moot. I'll check. EDIT2: No, the timeout still occurs. EDIT3: Hm, now I can't reproduce the timeout. Maybe I didn't rebuild the executable correctly before trying, so it was still using the old code. -
executing a command with ssh-pascal runs into timeout
dummzeuch replied to dummzeuch's topic in Network, Cloud and Web
Here you go: type TOnSshExecDataRecieve = procedure(const AData: TBytes; ADataLen: Int64) of object; // ... { Execute commands on the host and get Output/Errorcode back } ISshExec = interface ['{CA97A730-667A-4800-AF5D-77D5A4DDB192}'] procedure SetBufferSize(Size: Int64); procedure Cancel; // ---- change procedure SetOnStdErrReceive(ACallback: TOnSshExecDataRecieve); procedure SetOnStdOutReceive(ACallback: TOnSshExecDataRecieve); // ---- endchange procedure Exec(const Command: string; var Output, ErrOutput: string; var ExitCode: Integer); property BufferSize: Int64 write SetBufferSize; end; // ... type TSshExec = class(TInterfacedObject, ISshExec) private FSession : ISshSession; FBufferSize: Int64; FCancelled: Boolean; // ---- change FOnStdErrReceive: TOnSshExecDataRecieve; FOnStdOutReceive: TOnSshExecDataRecieve; procedure doOnStdErrReceive(const AData: TBytes; ADataLen: Int64); procedure doOnStdOutReceive(const AData: TBytes; ADataLen: Int64); // ---- end change procedure SetBufferSize(Size: Int64); procedure Cancel; procedure Exec(const Command: string; var Output, ErrOutput: string; var ExitCode: Integer); // ---- change procedure SetOnStdErrReceive(ACallback: TOnSshExecDataRecieve); procedure SetOnStdOutReceive(ACallback: TOnSshExecDataRecieve); // ---- end change public constructor Create(Session: ISshSession); end; // ... // ---- change procedure TSshExec.doOnStdErrReceive(const AData: TBytes; ADataLen: Int64); begin if Assigned(FOnStdErrReceive) then FOnStdErrReceive(AData, ADataLen); end; procedure TSshExec.doOnStdOutReceive(const AData: TBytes; ADataLen: Int64); begin if Assigned(FOnStdOutReceive) then FOnStdOutReceive(AData, ADataLen); end; // ---- end change procedure TSshExec.Exec(const Command: string; var Output, ErrOutput: string; var ExitCode: Integer); var Channel: PLIBSSH2_CHANNEL; M: TMarshaller; ReadBuffer, OutBuffer, ErrBuffer: TBytes; StdStream, ErrStream: TBytesStream; TimeVal: TTimeVal; ReadFds: TFdSet; BytesRead: ssize_t; ReturnCode: integer; OldBlocking: Boolean; begin if FSession.SessionState <> session_Authorized then raise ESshError.CreateRes(@Err_SessionAuth); FCancelled := False; Channel := libssh2_channel_open_session(FSession.Addr); if Channel = nil then CheckLibSsh2Result(libssh2_session_last_errno(FSession.Addr), FSession, 'libssh2_channel_open_session'); TimeVal.tv_sec := 1; // check for cancel every one second TimeVal.tv_usec := 0; StdStream := TBytesStream.Create(OutBuffer); ErrStream := TBytesStream.Create(ErrBuffer); SetLength(ReadBuffer, FBufferSize); OldBlocking := FSession.Blocking; FSession.Blocking := False; try Repeat ReturnCode := libssh2_channel_exec(Channel, M.AsAnsi(Command, FSession.CodePage).ToPointer); CheckLibSsh2Result(ReturnCode, FSession, 'libssh2_channel_exec'); Until ReturnCode <> LIBSSH2_ERROR_EAGAIN; // Stop waiting if cancelled of Channel is sent EOF while not FCancelled do begin // Wait until there is something to read on the Channel Repeat FD_ZERO(ReadFds); _FD_SET(FSession.Socket, ReadFds); ReturnCode := select(0, @ReadFds, nil, nil, @TimeVal); if ReturnCode < 0 then CheckSocketResult(WSAGetLastError, 'select'); if libssh2_channel_eof(Channel) = 1 then Break; Until (ReturnCode > 0) or FCancelled; try // Standard output BytesRead := libssh2_channel_read(Channel, PAnsiChar(ReadBuffer), FBufferSize); CheckLibSsh2Result(BytesRead, FSession, 'libssh2_channel_read_ex'); // ---- change if BytesRead > 0 then begin StdStream.WriteBuffer(ReadBuffer, BytesRead); DoOnStdOutReceive(ReadBuffer, BytesRead); end; // ---- end change // Error output BytesRead := libssh2_channel_read_stderr(Channel, PAnsiChar(ReadBuffer), FBufferSize); CheckLibSsh2Result(BytesRead, FSession, 'libssh2_channel_read_ex'); // ---- change if BytesRead > 0 then begin ErrStream.WriteBuffer(ReadBuffer, BytesRead); DoOnStdErrReceive(ReadBuffer, BytesRead); end; // ---- end change except on E: Exception do begin OutputDebugString(PChar(E.Message)); Break; end; end; // BytesRead will be either > 0 or LIBSSH2_ERROR_EAGAIN until // the command is processed if BytesRead = 0 then Break; end; Output := AnsiToUnicode(PAnsiChar(StdStream.Memory), StdStream.Size, FSession.CodePage); ErrOutput := AnsiToUnicode(PAnsiChar(ErrStream.Memory), ErrStream.Size, FSession.CodePage); // libssh2_channel_close sends SSH_MSG_CLOSE to the host libssh2_channel_close(Channel); if FCancelled then ExitCode := 130 // ^C on Linux else Exitcode := libssh2_channel_get_exit_status(Channel); finally StdStream.Free; ErrStream.Free; libssh2_channel_free(Channel); FSession.Blocking := OldBlocking; end; end; // ---- change procedure TSshExec.SetOnStdErrReceive(ACallback: TOnSshExecDataRecieve); begin FOnStdErrReceive := ACallback end; procedure TSshExec.SetOnStdOutReceive(ACallback: TOnSshExecDataRecieve); begin FOnStdOutReceive := ACallback; end; // ---- end change This passes the raw bytes received to the callback. Maybe it is possible to convert them to a string first? Or maybe call every time a line feed is received? Also, maybe the callbacks are enough so collecting the whole output is no longer necessary. I'll see how far I get with this. -
executing a command with ssh-pascal runs into timeout
dummzeuch replied to dummzeuch's topic in Network, Cloud and Web
I'll probably implement something like this (if I get the time to finish this project). I'll of course submit a patch in that case. -
executing a command with ssh-pascal runs into timeout
dummzeuch replied to dummzeuch's topic in Network, Cloud and Web
My problem is not that the main thread is blocked by the call but that I get the output of the command only after it has finished (which can take 30 minutes). During that time the output is received and stored in a memory stream to be converted to a string. Access to this partial output not available. I know that I could adapt the source code to change that behavior. But I was asking whether I may just be missing something (maybe a different interface?) in the library that already exists. @pyscripter Yes, I am (now) using the latest sources. No I haven't updated the binaries, but the problem is in the Delphi code. (Just in case you missed my edits in the original question: The timeout no longer occurs.) -
I for one loved Kylix, I even bought it twice - once through my employer (I partly owned the company at the time) and another one for personal use. That was a brief period when I hoped that Linux would actually take off on the desktop. Unfortunately, that never happened. Even now, with the end of support for Windows 10 looming and millions of perfectly usable computers in danger of being turned into electronic waste, Linux on the desktop is not gaining any visible market share.
-
Anybody remember OS/2? They had great support for running DOS and Windows 16 bit programs. So nobody bothered to write any native OS/2 programs. Guess what happened when Windows went 32 bits? (OK, that was not the only reason for OS/2's demise, but a big part of it.)
-
As always: Into the pockets of the parent company Idera. It's called a "Gewinnabführungsvertrag" in Germany. On the other hand how do you know that there are millions of Delphi users? And more importantly: Do you know that they have paid for a license recently? Maybe 99% of these supposed millions are still using Delphi 5 or 7?
-
Hm, on the Delphi history page it says: "Highest Position (since 2001): #6 in Oct 2001" But in the chart the maximum seems to be August 2004 with 5.87%: OK, one is the rank (#6 at 2.77%) the other is the percentage (5.87%), but it still seems odd.
-
I have multiple desktops created for my Windows 10 installation to easily switch between different tasks. When have the IDE open on one of these desktops, switch to a different one and then hibernate the PC, and later turn it on again, the IDE window shows up on the currently active desktop rather than the one where it was supposed to be. Create an additional Desktop on Windows (e.g. using the “Tasks” button on the taskbar). Start the Delphi IDE Switch to a different Desktop (e.g. using Win + Ctrl + Right) Now the IDE is no longer visible Hibernate the computer Turn on the computer again The IDE is now visible on the current Desktop, not on the one where it was supposed to be Has anybody else seen this happen? If yes, please comment on the bug report. https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-3281
-
Learning to make my own classes
dummzeuch replied to Skrim's topic in Algorithms, Data Structures and Class Design
Nowhere, as you noticed correctly. I should not try to answer any forum posts when reading on my mobile phone. I simply missed that part of the setter method. (And on the phone apparently syntax highlighting is also not possible 😞 ) One could argue though, that, if the name should not be empty, it should be initialized in the constructor and possibly not even have a setter at all. But if the property should be writable, it could be done in a setter method but still without requiring a getter method: type TEmployee = class private FName: string; public property Name: string read FName write SetName; end; procedure TEmployee.SetName(const Value: string); begin if value='' then raise Exception.Create('Name must have a value'); FName := value; end; -
Learning to make my own classes
dummzeuch replied to Skrim's topic in Algorithms, Data Structures and Class Design
If it's only about reading and writing values to the fields, there are two options: 1. Make the fields themselves public (and omit the 'F' prefix). If you later decide some of these fields should be properties, you can simply change the class without having to change the code that's using it. type TEmployee = class public Name: string; end; 2. Instead of having read and write accessor methods, declare the properties to directly access the fields: type TEmployee = class private FName: string; public property Name: string read FName write FName; end; -
The venerable Delphi IDE extension GExperts is about to undergo a revolutionary transformation, with plans announced to completely rewrite it using artificial intelligence and simultaneously port it to COBOL. This unexpected development marks a significant shift for a tool that has been a staple in the Delphi programming community for decades. The AI Rewrite: Starting Now The development team has just announced their decision to leverage artificial intelligence for the rewrite after facing increasing challenges maintaining the extensive codebase. What’s remarkable is the anticipated timeline – the team expects the entire process to take only a few hours once it begins. This unprecedented speed is attributed to advancements in AI code transformation technology. The AI system will analyze the entire GExperts source code, understanding its purpose, functionality, and even the quirks that make it uniquely useful to Delphi developers – all in a fraction of the time it would take human developers. Why COBOL? Perhaps the most surprising aspect of this transformation is the announced port to COBOL. This decision has raised eyebrows among the development community, as Delphi and COBOL represent dramatically different programming paradigms and eras. However, the team cites strategic reasoning behind this choice. COBOL continues to power critical systems in banking, insurance, and government sectors worldwide. This port will open GExperts to an entirely new ecosystem, potentially breathing new life into the project while serving developers maintaining legacy systems. Expected Timeline The project has not yet begun, but development is scheduled to start immediately. With the AI-powered transformation expected to take only a few hours from start to finish, the team anticipates having a functional COBOL version of GExperts available for testing within days rather than the months or years such a port would traditionally require. Looking Forward For developers interested in this innovative crossover, beta releases are expected to be available remarkably soon, with the team promising updates on the progress within the next 24 hours. This bold reinvention of GExperts, once completed, will demonstrate how established developer tools can evolve in unexpected ways, leveraging new technologies to reach broader audiences while maintaining their core value proposition. (Yes, AI is great! Even for writing April Fools jokes. Thanks to Claude.ai writing this only took a few minutes and it actually sounds like a press release some cool cloud AI blockchain outfit could have written.) Original blog post here.
-
AI Rewrite and COBOL Port Announced for Immediate Development
dummzeuch replied to dummzeuch's topic in GExperts
So you are saying that Elon Musk and those highly intelligent and capable people who work for him at DOGE don't know what they are talking about when they say they can convert the large COBOL code base to Java in months using AI? Or does that only apply if COBOL is the target language? -
AI Rewrite and COBOL Port Announced for Immediate Development
dummzeuch replied to dummzeuch's topic in GExperts
Thank you, but I am confident in using AI for the conversion. I'll call Elon Musk at DOGE for advice if necessary. -
AI Rewrite and COBOL Port Announced for Immediate Development
dummzeuch replied to dummzeuch's topic in GExperts
There is actually a connection between COBOLand Delphi: The company formerly known as Borland, who originally developed Delphi, was sold to Microfocus after spinning off the development tools to CodeGear. Microfocus was well known for Microfocus COBOL, which nowadays is called Visual COBOL and possibly includes some technologies Microfocus acquired in this process. But the real reason I came up with COBOL was the announced intention of DOGE to port the COBOL software to Java using AI in just a few months. So, if they succeed, we can expect to easily port the COBOL version of GExperts to Java. -
How do you think the following should be formatted? 1. Like this: type TClass = class(TObject) private FSomeField: integer; private const SomeConstant = 5; end; 2. Like this: type TClass = class(TObject) private FSomeField: integer; private const SomeConstant = 5; end; Note: This is only about code where the 'private const SomeConstant = 5;' is in one line without a line feed in between. And what about the following: 1. Like this: type TClass = class(TObject) private FSomeField: integer; private const SomeConstant = 5; FSomeOtherField: string; end; 2. Like this: type TClass = class(TObject) private FSomeField: integer; private const SomeConstant = 5; FSomeOtherField: string; end; Note: This is only about code where the 'private const SomeConstant = 5;' is in one line without a line feed in between.
-
Just to be clear: I'm not asking whether you like the 'private const bla=blub;' in one line syntax, but how it should be indented: 1. like 'private' on its own line -> same indentation as the class/record 2. like other constants / fields / types -> one indentation more than the class/record I assume that most (including myself) would like to split that line (whether between 'private' and 'const' or between 'const' and the identifier would be yet another point for debate.
-
No, I missed that one. This is a contrived example not real code, personally I always put a line feed after the visibility modifier and rather than using var I start a new visibility section.
-
We had Windows XP on some of our measurement vehicles until not too long ago. Working on these wasn't too bad really. I missed that I could not install some of the utilities I was used to back in the day. The main problem with using Windows XP nowadays would be that most of the current hard- and software no longer supports it.
-
I'll take XP back any time. From a user perspective, many of the real improvements of later Windows versions were available as add on tools for XP already. Other so called "improvements" are in fact not improvements at all. There is one notable exception: It's definitely an improvement that nowadays Windows pretty much means 64 bits and 8 Gig of RAM. There was a 64 bit version of XP too, but it wasn't widely used. As for Windows 98: I skipped that altogether, I went from Windows 3.1 (detouring over OS/2 2, 3 and 4 and even Linux for a short time) to Windows NT 4 and then XP. So Windows 95, 98 and ME just are names for me. But hey, I've only got another 8 years to retirement, so chances are that Windows 11 will be the last Windows version I have to suffer through. If I retire earlier, that would mean less years of using Windows as an added bonus. Or maybe I'll even switch careers from software development (in Delphi) to IT infrastructure, which is an important part of my current job anyway. But so far software development still is the part that's more fun.
-
Da das hier geklärt ist, schlage ich vor, die E-Mail Adressen in den Posts wieder zu löschen, sonst hagelt es nur unnötig Spam.
-
Is the Delphi 12.2 Error Insight, completion and CTRL+Click completely broken ?
dummzeuch replied to John R.'s topic in Delphi IDE and APIs
I have heard from others that they still have this problem with Delphi 12.3, but I have not seen this problem in my projects. I had it with several Projects in Delphi 10.2 though (which in turn work fine With Delphi 2007 and 12.3 though) Just an aside: GExperts has got an option in the Uses Clause Manger to look up the Unit that contains an identifier declaration (e.g. a Class type, but not a method) and open that unit with the cursor set to the line that contains this declaration. That's not quite the same functionality, but it might mitigate your problem a little bit. -
GExperts now fixes yet another annoyance in the Delphi IDE: Desktops
dummzeuch posted a topic in GExperts
With my particular monitor setup, the Desktop feature of the Delphi 11 and 12 IDE does not work correctly. The Startup Desktop is not restored as I saved it, on my high def monitor on the left hand side, but instead covers both monitors with huge window. I reported this problem to Embarcadero ages ago. The problem still exists in the recently released Delphi 12.3 (where I reported it again during the beta test phase). As I plan to switch to Delphi 12 in the medium future, I have now invested some more hours and added a workaround to GExperts that fixes the problem for me. It's in the current source code (revision #4466) in unit GX_ReselectDesktop, in case anybody is interested. I hope it does not break other people's installations. https://blog.dummzeuch.de/2025/03/16/gexperts-now-fixes-yet-another-annoyance-in-the-delphi-ide-desktops/