aehimself 396 Posted December 29, 2022 For the time being this is a teaser only, sources will be published on GitHub as soon as I finish up the rough edges. Due to the recent success of detecting and interacting with Delphi IDE versions / instances I decided to put together a new BDSLauncher, which allows you to set up rules to automatically decide which version and which instance of Delphi you want to open a Delphi source file with. If started without any parameters, the rule editor main window will show up: Here a list of file masks can be provided. If the file which is about to be open matches any of these, it will be opened in the version selected under. There are situations when a project has to be open for a .pas (.dfm more likely) to appear correctly. To support this, you can set a string which has to be contained in the IDE caption for it to be selected. If this is empty or there was no instances found with this criteria, a new instance will be launched with the parameters you specify (should be the main project .dproj / .dpk). If a parameter is specified (and the file indeed exists) two things can happen. Either a rule will decide which version / instance the selected file should be started in, or if there's none a selector will appear: If more rules would apply to the source file but the specified instance is not found, the last will be selected alphabetically. In case any rule was selected, no window is shown, only the IDE is launched and / or the source file is opened and the launcher will close shortly after. In theory, the new launcher should support all Delphi versions from 6 and up, however the DDE component used (to do the heavy lifting) was only tested with 7 and 10, 10.1, 10.2, 10.4 and 11. Settings are stored in AppData, so each user with access to the same PC can have different rules set up. What is left: Deeper testing after first impressions (especially with more Delphi versions. There are a few which I was forced to miss) Button / installer to change file associations to itself instead of the original BDSLauncher. This could also be used to reset these associations if a Delphi (un)installer messed these up More options (e.g. cmd/powershell/PascalScript scripting) to decide between versions / instances Allow manual rule ordering instead of the current alphabetical Add icons and / or redesign UI to be a bit more user friendly... It's kind of late now here - hence the teaser only - but I wanted to let you guys know that this is coming. Expect a new post with an alpha version in the upcoming days. 2 Share this post Link to post
dummzeuch 1506 Posted December 30, 2022 (edited) I might have missed it in your post, but for me the most important functionality for such a program would be to detect the correct Delphi version for a given project based on the contents of the dproj file. Of course that only matters if more than one Delphi version is available, and I'm probably an extreme in having all versions from Delphi 6 to 11 (with the exception of Delphi 8 ) installed on the same computer. Edited December 30, 2022 by dummzeuch autogenerated Smiley removed from desktop browser 1 Share this post Link to post
aehimself 396 Posted December 30, 2022 That is actually a good idea and wouldn’t be too hard I presume. If the information was found that version will be selected in the combo box by default. I’ll also have to rethink when the selector appears. It might be good for some to launch a new instance for each file and will probably find it very annoying that a window pops up each time a file was double clicked… As a last resort a “catch-all” rule could be set up to hide the popup… Anyway, I’ll have to think this through. Share this post Link to post
dummzeuch 1506 Posted December 30, 2022 26 minutes ago, aehimself said: That is actually a good idea and wouldn’t be too hard I presume. If the information was found that version will be selected in the combo box by default. The .dproj file contains a version entry which is unique for most Delphi versions (unfortunately not for all of them), see the Delphi Wiki How to find out which Delphi version was used to create a project? (Or you can simple take the source code for that detection from my dzBdsLauncher, assuming that the licenses are compatible.) Share this post Link to post
Attila Kovacs 629 Posted December 30, 2022 Or you could save an extra file in the project dir like .idever Share this post Link to post
dummzeuch 1506 Posted December 30, 2022 15 minutes ago, Attila Kovacs said: Or you could save an extra file in the project dir like .idever Which only works for frequently used projects but not in the case that you just downloaded / checked out some sources from e.g. GitHub or SourceForge. Share this post Link to post
Attila Kovacs 629 Posted December 30, 2022 1 minute ago, dummzeuch said: Which only works for frequently used projects but not in the case that you just downloaded / checked out some sources from e.g. GitHub or SourceForge. Yes, if the file is missing then there is the dproj or a selection splash screen, but I would priorate a config file. Share this post Link to post
aehimself 396 Posted December 30, 2022 Source can be obtained at https://github.com/aehimself/BDSLauncher. Some small changes have been made: If no caption filter is set, it means any running instance can be chosen to open the file with. Always use a new instance is now a separate option If there's only one installed version and no running instances are found, no selector will be shown, a new instance is launched automatically File associations can be taken over and given back to the previous Delphi. For the time being this only includes .pas, .dpr, .dproj, .dfm and .groupproj Left to do: Everything mentioned in the first post At the moment all the file associations are taken over with the description "AE BDSLauncher file" and the same icon as the application. In reality it should be separated, like how original Delphi does it Attempting to guess the Delphi version in .dpr and .dproj files based on @dummzeuch's request Feel free to try it out but don't expect it to work perfectly and look nice 🙂 Share this post Link to post
Attila Kovacs 629 Posted December 30, 2022 I think you can remove POSTED_DDE_ACK 1 Share this post Link to post
aehimself 396 Posted January 2, 2023 Some items from the to-do list are completed: File associations are now created by copying all details from the current Delphi association. This means that (in theory) icons and descriptions will stay the same, but launched with AE BDSLauncher. Unfortunately I could not test this because my associations were already messed up by Delphi and have no icons of anything... 😕 If no rule was able to launch the file, the version selector will select the Delphi version based on the contents of the .dproj, .bdsproj or .dof file. If it was created with a version which is not installed, an error message is shown, and the latest version is selected. Rules are now parsed based on an actual order, not alphabetically. For the time being reordering only can be done with the "Move up" or "Move down" option, I'll extend this with the classic drag & drop in the future. Also, Fixed some appearance issues and an AV if the program is started up with no rules Fixed parameter handling. Quotes are now removed if quoted, if unquoted all parameters will be appended to a single file name. Therefore, these two commands will be able to open the file correctly: BDSLauncher "C:\Path to my project\Project1.dproj" and BDSLauncher C:\Path to my project\Project1.dproj I'll probably beautify the detection code to similar of what dzBdsLauncher has as it's a lot more sophisticated than my if-s but at least it was quick to write 🙂 Due to detection is now possible, I'll probably add it as a possible option for a Delphi version in the rules. 1 Share this post Link to post
aehimself 396 Posted January 5, 2023 There were numerous updates since the last post: Auto-detect Delphi version is now a valid option in rules Window sizes are saved and restored when launched again Added extensive logging in case something goes wrong An icon now appears on the taskbar if only version selector window is shown Rules can be rearranged with drag & drop and can be renamed Changed how rules appear in the list, making it a bit more eye-friendly Version selector window can be closed with the ESC key If Shift is pressed while a file is launched, rule checks will be bypassed and the version selector will show up instead A single file can be launched from the rule editor (main) window. The launching process is exactly the same so it can be used to test the rules The logic for rule processing and opening a file by any rules has been moved to the main form, now RuleEngine only stores the rules - as it should I also had the chance to move it to my developer VM and can confirm that the following are working properly: Taking over file extensions do preserve icons and descriptions Project Version detection is working properly: Delphi 7, 10, 10.1, 10.2, 10.4 and 11.2 is detected and can be controlled: I did have an issue when starting a file width Delphi 7 as it kept popping messages up that some packages couldn't be loaded. As any file could be launched from the command line I suspect maybe UAC / other permission issue and I might need to add some more parameters to the CreateProcess I'm currently using. However, after I pressed Yes on all of these the problem simply went away by itself... so I'll not be able to experiment and debug it anymore 😞 Share this post Link to post
Attila Kovacs 629 Posted January 5, 2023 I'm not sure a combobox is the right decision here as it will slow down the process. I'd stick with a listbox or grid or similar with RETURN key and a button for the rookies. 1 Share this post Link to post
aehimself 396 Posted January 6, 2023 I seriously suck at UI design so tips like this are more than welcome 🙂 Changed the version selector to show up as a list instead and it indeed feels nicer to handle: 1 Share this post Link to post
dummzeuch 1506 Posted January 6, 2023 1 hour ago, aehimself said: I seriously suck at UI design so tips like this are more than welcome 🙂 Changed the version selector to show up as a list instead and it indeed feels nicer to handle: This large Open button does not look good either. I think a panel with an Open and a Cancel button of a standard size on the right hand side would look better. But this is just my personal taste. Share this post Link to post
ringli 1 Posted January 6, 2023 (edited) I have made some changes to the BDSLauncher that may be useful to the general public. I had the problem that the rule "*\My Projects\Project Name\*.dproj" was not recognized as true by the used function "System.Masks.MatchesMask". Therefore I made the following changes in the unit "uBDSLauncherMainForm": Unit uBDSLauncherMainForm; Interface Uses ... Type ... // // Replacement for MatchesMask from Unit System.Masks // function PathMatchSpecEx(pszFile, pszSpec : LPCWSTR; dwFlags : DWORD) : HRESULT; stdcall; .... Implementation Uses ... // // Replacement for MatchesMask from Unit System.Masks // function PathMatchSpecEx; external 'shlwapi.dll' name 'PathMatchSpecExW'; function BDSMatchesMask(const pszFile, pszSpec : String) : Boolean; const PMSF_NORMAL = $000000; PMSF_MULTIPLE = $00000001; begin Result := PathMatchSpecEx(PChar(pszFile), PChar(pszSpec), PMSF_NORMAL or PMSF_MULTIPLE) = S_OK; end; .... Function TBDSLauncherMainForm.OpenWithRules(Const inFileName, inDetectedVersion: String): Boolean; Var ... Begin ... For mask In rule.FileMasks.Split([sLineBreak]) Do //anymatch := anymatch Or MatchesMask(inFileName, mask); anymatch := anymatch Or BDSMatchesMask(inFileName, mask); ... Another change I have made in the unit "AE.IDE.DelphiVersions". Reason was here that there is with me in the Registry the path "HKCU\SOFTWARE\Embarcadero\BDS\_22.0". The underscore then led to the error "'_22' is not a valid integer value for type 'Integer'". Unit AE.IDE.DelphiVersions; Interface Uses ... Type ... Implementation Uses ... .... Procedure TAEDelphiVersions.DiscoverVersions(Const inRegistry: TRegistry; Const inDelphiVersionClass: TAEDelphiVersionClass); Var ... Begin ... //Self.AddVersion(inDelphiVersionClass.Create(Self, inRegistry.ReadString('App'), Integer.Parse(s.Substring(0, s.IndexOf('.'))))); var arr : TArray<string> := s.Split(['.']); var ver : Integer := StrToIntDef(arr[0], 0); if ver > 0 then begin Self.AddVersion(inDelphiVersionClass.Create(Self, inRegistry.ReadString('App'), ver)); end; Finally ... Edited January 6, 2023 by ringli 1 Share this post Link to post
aehimself 396 Posted January 6, 2023 Invalid registry key handling (and due to this, an additional version number detection) has been incorporated in TAEDelphiVersions, thank you for pointing this out! As for the masking, which Delphi version are you using? If MatchesMask('C:\My projects\Project name\Project1.dproj', '*\My projects\Project name\*.dproj') Then ShowMessage('Success!') Else ShowMessage('Fail...'); If MatchesMask('C:\My projects\Project name\Project1.dproj', '*\My projects\*.dproj') Then ShowMessage('Success!') Else ShowMessage('Fail...'); If MatchesMask('C:\Temp\My projects\Project name\Project1.dproj', '*\My projects\*.dproj') Then ShowMessage('Success!') Else ShowMessage('Fail...'); On 11.2 all shows "Success" for me. Share this post Link to post
aehimself 396 Posted January 6, 2023 2 hours ago, dummzeuch said: This large Open button does not look good either. I think a panel with an Open and a Cancel button of a standard size on the right hand side would look better. But this is just my personal taste. You are right, it definitely looks cleaner: As a bonus, with the Cancel button present I can remove the code to handle the Esc keypress 🙂 Share this post Link to post
ringli 1 Posted January 6, 2023 29 minutes ago, aehimself said: On 11.2 all shows "Success" for me. That is strange. I am also using Delphi 11.2 here. I have tested it a few more times now and currently the phenomenon is not traceable. If it occurs again I will try to narrow down the problem further. Share this post Link to post