Subversion Repositories userdetect2

Rev

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