Subversion Repositories userdetect2

Rev

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