Subversion Repositories userdetect2

Rev

Rev 81 | Rev 83 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit UD2_Main;
  2.  
  3. interface
  4.  
  5. {$IF CompilerVersion >= 25.0}
  6. {$LEGACYIFEND ON}
  7. {$IFEND}
  8.  
  9. {$INCLUDE 'UserDetect2.inc'}
  10.  
  11. uses
  12.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  13.   Dialogs, StdCtrls, Grids, ValEdit, UD2_Obj, ComCtrls, ImgList, ExtCtrls,
  14.   CommCtrl, Menus, VTSListView, VTSCompat;
  15.  
  16. const
  17.   DefaultIniFile = 'UserDetect2.ini';
  18.   DefaultWarnIfNothingMatches = 'false';
  19.   TagWarnIfNothingMatches = 'WarnIfNothingMatches';
  20.   DefaultCloseAfterLaunching = 'false';
  21.   TagCloseAfterLaunching = 'CloseAfterLaunching';
  22.   TagIcon = 'Icon';
  23.  
  24. type
  25.   TUD2MainForm = class(TForm)
  26.     OpenDialog1: TOpenDialog;
  27.     PageControl1: TPageControl;
  28.     TasksTabSheet: TTabSheet;
  29.     TabSheet2: TTabSheet;
  30.     TabSheet3: TTabSheet;
  31.     IniTemplateMemo: TMemo;
  32.     TabSheet4: TTabSheet;
  33.     TasksListView: TVTSListView;
  34.     TasksImageList: TImageList;
  35.     SaveDialog1: TSaveDialog;
  36.     TabSheet5: TTabSheet;
  37.     Image1: TImage;
  38.     Label1: TLabel;
  39.     Label2: TLabel;
  40.     Label3: TLabel;
  41.     Label4: TLabel;
  42.     Label5: TLabel;
  43.     Label6: TLabel;
  44.     Label7: TLabel;
  45.     Label8: TLabel;
  46.     LoadedPluginsListView: TVTSListView;
  47.     IdentificationsListView: TVTSListView;
  48.     ErrorsTabSheet: TTabSheet;
  49.     ErrorsMemo: TMemo;
  50.     Memo1: TMemo;
  51.     Panel1: TPanel;
  52.     Button1: TButton;
  53.     Button2: TButton;
  54.     TasksPopupMenu: TPopupMenu;
  55.     Run1: TMenuItem;
  56.     Properties1: TMenuItem;
  57.     IdentificationsPopupMenu: TPopupMenu;
  58.     CopyTaskDefinitionExample1: TMenuItem;
  59.     Button3: TButton;
  60.     VersionLabel: TLabel;
  61.     LoadedPluginsPopupMenu: TPopupMenu;
  62.     MenuItem1: TMenuItem;
  63.     Panel2: TPanel;
  64.     Image2: TImage;
  65.     procedure FormDestroy(Sender: TObject);
  66.     procedure TasksListViewDblClick(Sender: TObject);
  67.     procedure TasksListViewKeyPress(Sender: TObject; var Key: Char);
  68.     procedure Button1Click(Sender: TObject);
  69.     procedure Button2Click(Sender: TObject);
  70.     procedure URLLabelClick(Sender: TObject);
  71.     procedure TasksPopupMenuPopup(Sender: TObject);
  72.     procedure Run1Click(Sender: TObject);
  73.     procedure Properties1Click(Sender: TObject);
  74.     procedure IdentificationsPopupMenuPopup(Sender: TObject);
  75.     procedure CopyTaskDefinitionExample1Click(Sender: TObject);
  76.     procedure ListViewCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer);
  77.     procedure Button3Click(Sender: TObject);
  78.     procedure LoadedPluginsPopupMenuPopup(Sender: TObject);
  79.     procedure MenuItem1Click(Sender: TObject);
  80.     procedure FormCreate(Sender: TObject);
  81.   protected
  82.     ud2: TUD2;
  83.     procedure LoadTaskList;
  84.     procedure LoadDetectedIDs;
  85.     procedure LoadINITemplate;
  86.     procedure LoadLoadedPluginList;
  87.     function GetIniFileName: string;
  88.     procedure DoRun(ShortTaskName: string);
  89.     procedure CheckForErrors;
  90.   public
  91.     procedure Run;
  92.   end;
  93.  
  94. var
  95.   UD2MainForm: TUD2MainForm;
  96.  
  97. implementation
  98.  
  99. {$R *.dfm}
  100.  
  101. uses
  102.   ShellAPI, Clipbrd, Math, AlphaNumSort, UD2_Utils, UD2_TaskProperties;
  103.  
  104. type
  105.   TUD2ListViewEntry = class(TObject)
  106.     ShortTaskName: string;
  107.     CloseAfterLaunching: boolean;
  108.     TaskPropertiesForm: TForm;
  109.   end;
  110.  
  111. function AddIconRecToImageList(rec: TIconFileIdx; ImageList: TImageList): integer;
  112. var
  113.   icon: TIcon;
  114. begin
  115.   icon := TIcon.Create;
  116.   try
  117.     icon.Handle := ExtractIcon(Application.Handle, PChar(rec.FileName), rec.IconIndex);
  118.  
  119.     // result := ImageList.AddIcon(ico);
  120.     result := AddTransparentIconToImageList(ImageList, icon);
  121.   finally
  122.     icon.Free;
  123.   end;
  124. end;
  125.  
  126. { TUD2MainForm }
  127.  
  128. function TUD2MainForm.GetIniFileName: string;
  129. resourcestring
  130.   LNG_FILE_NOT_FOUND = 'File "%s" not found.';
  131. begin
  132.   if (ParamCount >= 1) and not CheckBoolParam(1, 'C') then
  133.   begin
  134.     if FileExists(ParamStr(1)) then
  135.     begin
  136.       result := ParamStr(1);
  137.     end
  138.     else
  139.     begin
  140.       ExitCode := EXITCODE_INI_NOT_FOUND;
  141.       MessageDlg(Format(LNG_FILE_NOT_FOUND, [ParamStr(1)]), mtError, [mbOK], 0);
  142.       result := '';
  143.     end;
  144.     Exit;
  145.   end
  146.   else
  147.   begin
  148.     if FileExists(DefaultIniFile) then
  149.     begin
  150.       result := DefaultIniFile;
  151.       Exit;
  152.     end;
  153.  
  154.     if FileExists(GetOwnCmdName + '.ini') then
  155.     begin
  156.       result := GetOwnCmdName + '.ini';
  157.       Exit;
  158.     end;
  159.  
  160.     if CompatOpenDialogExecute(OpenDialog1) then
  161.     begin
  162.       result := OpenDialog1.FileName;
  163.       Exit;
  164.     end;
  165.  
  166.     result := '';
  167.     Exit;
  168.   end;
  169. end;
  170.  
  171. procedure TUD2MainForm.LoadTaskList;
  172. var
  173.   sl: TStringList;
  174.   i: integer;
  175.   ShortTaskName, iconString: string;
  176.   iconIndex: integer;
  177.   obj: TUD2ListViewEntry;
  178. begin
  179.   TasksListView.Clear;
  180.   sl := TStringList.Create;
  181.   try
  182.     ud2.GetTaskListing(sl);
  183.     for i := 0 to sl.Count-1 do
  184.     begin
  185.       ShortTaskName := sl.Names[i];
  186.  
  187.       Obj := TUD2ListViewEntry.Create;
  188.       Obj.ShortTaskName := ShortTaskName;
  189.       Obj.CloseAfterLaunching := ud2.ReadMetatagBool(ShortTaskName, TagCloseAfterLaunching, DefaultCloseAfterLaunching);
  190.  
  191.       TasksListView.AddItem(sl.Values[ShortTaskName], TObject(Obj));
  192.  
  193.       iconString := ud2.ReadMetatagString(ShortTaskName, TagIcon, '');
  194.       if iconString <> '' then
  195.       begin
  196.         iconIndex := AddIconRecToImageList(SplitIconString(iconString), TasksImageList);
  197.         if iconIndex <> -1 then
  198.         begin
  199.           TasksListView.Items.Item[TasksListView.Items.Count-1].ImageIndex := iconIndex;
  200.         end;
  201.       end;
  202.     end;
  203.   finally
  204.     sl.Free;
  205.   end;
  206. end;
  207.  
  208. procedure TUD2MainForm.DoRun(ShortTaskName: string);
  209. resourcestring
  210.   LNG_TASK_NOT_EXISTS = 'The task "%s" does not exist in the INI file.';
  211.   LNG_NOTHING_MATCHES = 'No identification string matches to your environment. No application was launched. Please check the Task Definition File.';
  212. var
  213.   slCmds: TStringList;
  214.   i: integer;
  215.   cmd: string;
  216. begin
  217.   if not ud2.TaskExists(ShortTaskName) then
  218.   begin
  219.     // This can happen if the task name is taken from command line
  220.     MessageDlg(Format(LNG_TASK_NOT_EXISTS, [ShortTaskName]), mtError, [mbOK], 0);
  221.     ExitCode := EXITCODE_TASK_NOT_EXISTS;
  222.     Exit;
  223.   end;
  224.  
  225.   slCmds := TStringList.Create;
  226.   try
  227.     ud2.GetCommandList(ShortTaskName, slCmds);
  228.  
  229.     if (slCmds.Count = 0) and ud2.ReadMetatagBool(ShortTaskName, TagWarnIfNothingMatches, DefaultWarnIfNothingMatches) then
  230.     begin
  231.       MessageDlg(LNG_NOTHING_MATCHES, mtWarning, [mbOK], 0);
  232.       ExitCode := EXITCODE_TASK_NOTHING_MATCHES;
  233.     end;
  234.  
  235.     for i := 0 to slCmds.Count-1 do
  236.     begin
  237.       cmd := slCmds.Strings[i];
  238.       if cmd = '' then continue;
  239.       UD2_RunCMD(cmd, SW_NORMAL); // Idea: Let SW_NORMAL be configurable by the user?
  240.     end;
  241.   finally
  242.     slCmds.Free;
  243.   end;
  244. end;
  245.  
  246. procedure TUD2MainForm.FormDestroy(Sender: TObject);
  247. var
  248.   i: integer;
  249. begin
  250.   if Assigned(ud2) then ud2.Free;
  251.   for i := 0 to TasksListView.Items.Count-1 do
  252.   begin
  253.     TUD2ListViewEntry(TasksListView.Items.Item[i].Data).Free;
  254.   end;
  255. end;
  256.  
  257. procedure TUD2MainForm.CheckForErrors;
  258. begin
  259.   ErrorsTabSheet.TabVisible := ud2.Errors.Count > 0;
  260.   if ErrorsTabSheet.TabVisible then
  261.   begin
  262.     ErrorsMemo.Lines.Assign(ud2.Errors);
  263.     PageControl1.ActivePage := ErrorsTabSheet;
  264.   end;
  265. end;
  266.  
  267. procedure TUD2MainForm.LoadDetectedIDs;
  268. var
  269.   i, j: integer;
  270.   pl: TUD2Plugin;
  271.   ude: TUD2IdentificationEntry;
  272. begin
  273.   IdentificationsListView.Clear;
  274.   for i := 0 to ud2.LoadedPlugins.Count-1 do
  275.   begin
  276.     pl := ud2.LoadedPlugins.Items[i] as TUD2Plugin;
  277.     for j := 0 to pl.DetectedIdentifications.Count-1 do
  278.     begin
  279.       ude := pl.DetectedIdentifications.Items[j] as TUD2IdentificationEntry;
  280.       with IdentificationsListView.Items.Add do
  281.       begin
  282.         Caption := pl.PluginName;
  283.         SubItems.Add(pl.IdentificationMethodName);
  284.         SubItems.Add(ude.IdentificationString);
  285.         SubItems.Add(GUIDToString(pl.PluginGUID));
  286.       end;
  287.     end;
  288.   end;
  289.  
  290.   for i := 0 to IdentificationsListView.Columns.Count-1 do
  291.   begin
  292.     IdentificationsListView.Columns.Items[i].Width := LVSCW_AUTOSIZE_USEHEADER;
  293.   end;
  294. end;
  295.  
  296. procedure TUD2MainForm.LoadINITemplate;
  297. var
  298.   i, j: integer;
  299.   pl: TUD2Plugin;
  300.   ude: TUD2IdentificationEntry;
  301. begin
  302.   IniTemplateMemo.Clear;
  303.   IniTemplateMemo.Lines.Add('[ExampleTask1]');
  304.   IniTemplateMemo.Lines.Add('; Description: Optional but recommended');
  305.   IniTemplateMemo.Lines.Add('Description=Run Task #1');
  306.   IniTemplateMemo.Lines.Add('; WarnIfNothingMatches: Warns when no application was launched. Default: false.');
  307.   IniTemplateMemo.Lines.Add('WarnIfNothingMatches=false');
  308.   IniTemplateMemo.Lines.Add('; Optional: IconDLL + IconIndex');
  309.   IniTemplateMemo.Lines.Add('Icon=%SystemRoot%\system32\Shell32.dll,3');
  310.   IniTemplateMemo.Lines.Add('; Optional: Can be true or false');
  311.   IniTemplateMemo.Lines.Add(TagCloseAfterLaunching+'=true');
  312.  
  313.   for i := 0 to ud2.LoadedPlugins.Count-1 do
  314.   begin
  315.     pl := ud2.LoadedPlugins.Items[i] as TUD2Plugin;
  316.     for j := 0 to pl.DetectedIdentifications.Count-1 do
  317.     begin
  318.       ude := pl.DetectedIdentifications.Items[j] as TUD2IdentificationEntry;
  319.       IniTemplateMemo.Lines.Add(Format('; %s', [ude.Plugin.PluginName]));
  320.       IniTemplateMemo.Lines.Add(ude.GetPrimaryIdName+'=calc.exe');
  321.     end;
  322.   end;
  323. end;
  324.  
  325. procedure TUD2MainForm.LoadLoadedPluginList;
  326. resourcestring
  327.   LNG_MS = '%dms';
  328. var
  329.   i: integer;
  330.   pl: TUD2Plugin;
  331. begin
  332.   LoadedPluginsListView.Clear;
  333.   for i := 0 to ud2.LoadedPlugins.Count-1 do
  334.   begin
  335.     pl := ud2.LoadedPlugins.Items[i] as TUD2Plugin;
  336.     with LoadedPluginsListView.Items.Add do
  337.     begin
  338.       Caption := pl.PluginDLL;
  339.       SubItems.Add(pl.PluginVendor);
  340.       SubItems.Add(pl.PluginName);
  341.       SubItems.Add(pl.PluginVersion);
  342.       SubItems.Add(pl.IdentificationMethodName);
  343.       SubItems.Add(IntToStr(pl.DetectedIdentifications.Count));
  344.       SubItems.Add(Format(LNG_MS, [Max(1,pl.time)])); // at least show 1ms, otherwise it would be unloggical
  345.       SubItems.Add(pl.IdentificationProcedureStatusCodeDescribed);
  346.       SubItems.Add(pl.PluginGUIDString);
  347.     end;
  348.   end;
  349.  
  350.   for i := 0 to LoadedPluginsListView.Columns.Count-1 do
  351.   begin
  352.     LoadedPluginsListView.Columns.Items[i].Width := LVSCW_AUTOSIZE_USEHEADER;
  353.   end;
  354. end;
  355.  
  356. procedure TUD2MainForm.TasksListViewDblClick(Sender: TObject);
  357. var
  358.   obj: TUD2ListViewEntry;
  359. begin
  360.   if TasksListView.ItemIndex = -1 then exit;
  361.   obj := TUD2ListViewEntry(TasksListView.Selected.Data);
  362.   DoRun(obj.ShortTaskName);
  363.   if obj.CloseAfterLaunching then Close;
  364. end;
  365.  
  366. procedure TUD2MainForm.TasksListViewKeyPress(Sender: TObject; var Key: Char);
  367. begin
  368.   if Key = #13 then
  369.   begin
  370.     TasksListViewDblClick(Sender);
  371.   end;
  372. end;
  373.  
  374. procedure TUD2MainForm.Button1Click(Sender: TObject);
  375. begin
  376.   UD2_RunCMD(ud2.IniFileName, SW_NORMAL);
  377. end;
  378.  
  379. procedure TUD2MainForm.Button2Click(Sender: TObject);
  380. begin
  381.   if CompatSaveDialogExecute(SaveDialog1) then
  382.   begin
  383.     IniTemplateMemo.Lines.SaveToFile(SaveDialog1.FileName);
  384.   end;
  385. end;
  386.  
  387. procedure TUD2MainForm.URLLabelClick(Sender: TObject);
  388. var
  389.   s: string;
  390. begin
  391.   s := TLabel(Sender).Caption;
  392.   if Pos('@', s) > 0 then
  393.     s := 'mailto:' + s
  394.   else
  395.     s := 'http://' + s;
  396.   UD2_RunCMD(s, SW_NORMAL);
  397. end;
  398.  
  399. procedure TUD2MainForm.TasksPopupMenuPopup(Sender: TObject);
  400. begin
  401.   Run1.Enabled := TasksListView.ItemIndex <> -1;
  402.   Properties1.Enabled := TasksListView.ItemIndex <> -1;
  403. end;
  404.  
  405. procedure TUD2MainForm.Run1Click(Sender: TObject);
  406. begin
  407.   TasksListViewDblClick(Sender);
  408. end;
  409.  
  410. procedure TUD2MainForm.Properties1Click(Sender: TObject);
  411. var
  412.   obj: TUD2ListViewEntry;
  413. begin
  414.   if TasksListView.ItemIndex = -1 then exit;
  415.   obj := TUD2ListViewEntry(TasksListView.Selected.Data);
  416.   if obj.TaskPropertiesForm = nil then
  417.   begin
  418.     obj.TaskPropertiesForm := TUD2TaskPropertiesForm.Create(Self, ud2, obj.ShortTaskName);
  419.   end;
  420.   obj.TaskPropertiesForm.Show;
  421. end;
  422.  
  423. procedure TUD2MainForm.IdentificationsPopupMenuPopup(Sender: TObject);
  424. begin
  425.   CopyTaskDefinitionExample1.Enabled := IdentificationsListView.ItemIndex <> -1;
  426. end;
  427.  
  428. procedure TUD2MainForm.CopyTaskDefinitionExample1Click(Sender: TObject);
  429. var
  430.   s: string;
  431. begin
  432.   s := '; '+IdentificationsListView.Selected.Caption+#13#10+
  433.        IdentificationsListView.Selected.SubItems[0] + ':' + IdentificationsListView.Selected.SubItems[1] + '=calc.exe'+#13#10+
  434.        #13#10+
  435.        '; Alternatively:'+#13#10+
  436.        IdentificationsListView.Selected.SubItems[2] + ':' + IdentificationsListView.Selected.SubItems[1] + '=calc.exe'+#13#10;
  437.   Clipboard.AsText := s;
  438. end;
  439.  
  440. procedure TUD2MainForm.ListViewCompare(Sender: TObject; Item1,
  441.   Item2: TListItem; Data: Integer; var Compare: Integer);
  442. var
  443.   ListView: TVTSListView;
  444. begin
  445.   ListView := Sender as TVTSListView;
  446.   if ListView.CurSortedColumn = 0 then
  447.   begin
  448.     Compare := AlphaNumCompare(Item1.Caption, Item2.Caption);
  449.   end
  450.   else
  451.   begin
  452.     Compare := AlphaNumCompare(Item1.SubItems[ListView.CurSortedColumn-1],
  453.                                Item2.SubItems[ListView.CurSortedColumn-1]);
  454.   end;
  455.   if ListView.CurSortedDesc then Compare := -Compare;
  456. end;
  457.  
  458. procedure TUD2MainForm.Button3Click(Sender: TObject);
  459. begin
  460.   VTS_CheckUpdates('userdetect2', VersionLabel.Caption);
  461. end;
  462.  
  463. procedure TUD2MainForm.LoadedPluginsPopupMenuPopup(Sender: TObject);
  464. begin
  465.   MenuItem1.Enabled := LoadedPluginsListView.ItemIndex <> -1;
  466. end;
  467.  
  468. procedure TUD2MainForm.MenuItem1Click(Sender: TObject);
  469. var
  470.   s: string;
  471. begin
  472.   s := '; ' + LoadedPluginsListView.Selected.SubItems.Strings[6];
  473.   Clipboard.AsText := s;
  474. end;
  475.  
  476. procedure TUD2MainForm.Run;
  477. resourcestring
  478.   LNG_SYNTAX = 'Syntax: %s [TaskDefinitionFile [/T TaskName] | /C IdentificationTerm [Command] | /?]';
  479. var
  480.   LoadedIniFile: string;
  481. begin
  482.   ExitCode := EXITCODE_OK;
  483.  
  484.   if ((ParamCount = 1) and CheckBoolParam(1, '?')) or
  485.      (CheckBoolParam(2, 'T') and (ParamCount > 3)) or
  486.      (CheckBoolParam(1, 'C') and (ParamCount > 3)) or
  487.      (not CheckBoolParam(2, 'T') and not CheckBoolParam(1, 'C') and (ParamCount > 1)) then
  488.   begin
  489.     ExitCode := EXITCODE_SYNTAX_ERROR;
  490.     MessageDlg(Format(LNG_SYNTAX, [GetOwnCmdName]), mtInformation, [mbOK], 0);
  491.  
  492.     Visible := false;
  493.     Close;
  494.     Exit;
  495.   end;
  496.  
  497.   LoadedIniFile := GetIniFileName;
  498.   if LoadedIniFile = '' then
  499.   begin
  500.     Visible := false;
  501.     Close;
  502.     Exit;
  503.   end;
  504.   ud2 := TUD2.Create(LoadedIniFile);
  505.  
  506.   ud2.HandlePluginDir('',        '*.udp');
  507.   ud2.HandlePluginDir('Plugins', '*.udp');
  508.   ud2.HandlePluginDir('Plugins', '*.dll');
  509.  
  510.   if CheckBoolParam(1, 'C') then
  511.   begin
  512.     if ud2.FulfilsEverySubterm(ParamStr(2)) then
  513.     begin
  514.       ExitCode := EXITCODE_OK;
  515.  
  516.       if ParamStr(3) <> '' then UD2_RunCMD(ParamStr(3), SW_NORMAL); // Idea: SW_NORMAL changeable via parameter
  517.     end
  518.     else
  519.     begin
  520.       ExitCode := EXITCODE_TASK_NOTHING_MATCHES;
  521.     end;
  522.  
  523.     Visible := false;
  524.     Close;
  525.     Exit;
  526.   end
  527.   else if CheckBoolParam(2, 'T') then
  528.   begin
  529.     DoRun(ParamStr(3));
  530.  
  531.     Visible := false;
  532.     Close;
  533.     Exit;
  534.   end
  535.   else
  536.   begin
  537.     LoadTaskList;
  538.     LoadDetectedIDs;
  539.     LoadINITemplate;
  540.     LoadLoadedPluginList;
  541.     CheckForErrors;
  542.  
  543.     Visible := true;
  544.     Exit;
  545.   end;
  546. end;
  547.  
  548. procedure TUD2MainForm.FormCreate(Sender: TObject);
  549. begin
  550.   // To avoid accidental change of the default tab from the IDE VCL Designer
  551.   PageControl1.ActivePage := TasksTabSheet;
  552. end;
  553.  
  554. end.
  555.