Subversion Repositories userdetect2

Rev

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