Subversion Repositories userdetect2

Rev

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

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