Subversion Repositories userdetect2

Rev

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

Rev Author Line No. Line
68 daniel-mar 1
unit UD2_Main;
2
 
3
interface
4
 
5
{$IF CompilerVersion >= 25.0}
6
{$LEGACYIFEND ON}
7
{$IFEND}
8
 
70 daniel-mar 9
{$INCLUDE 'UserDetect2.inc'}
10
 
68 daniel-mar 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;
73 daniel-mar 33
    TasksListView: TVTSListView;
34
    TasksImageList: TImageList;
68 daniel-mar 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;
73 daniel-mar 46
    LoadedPluginsListView: TVTSListView;
47
    IdentificationsListView: TVTSListView;
68 daniel-mar 48
    ErrorsTabSheet: TTabSheet;
49
    ErrorsMemo: TMemo;
50
    Memo1: TMemo;
51
    Panel1: TPanel;
52
    Button1: TButton;
53
    Button2: TButton;
73 daniel-mar 54
    TasksPopupMenu: TPopupMenu;
68 daniel-mar 55
    Run1: TMenuItem;
56
    Properties1: TMenuItem;
73 daniel-mar 57
    IdentificationsPopupMenu: TPopupMenu;
68 daniel-mar 58
    CopyTaskDefinitionExample1: TMenuItem;
59
    Button3: TButton;
60
    VersionLabel: TLabel;
73 daniel-mar 61
    LoadedPluginsPopupMenu: TPopupMenu;
62
    MenuItem1: TMenuItem;
81 daniel-mar 63
    Panel2: TPanel;
64
    Image2: TImage;
68 daniel-mar 65
    procedure FormDestroy(Sender: TObject);
73 daniel-mar 66
    procedure TasksListViewDblClick(Sender: TObject);
67
    procedure TasksListViewKeyPress(Sender: TObject; var Key: Char);
68 daniel-mar 68
    procedure Button1Click(Sender: TObject);
69
    procedure Button2Click(Sender: TObject);
70
    procedure URLLabelClick(Sender: TObject);
73 daniel-mar 71
    procedure TasksPopupMenuPopup(Sender: TObject);
68 daniel-mar 72
    procedure Run1Click(Sender: TObject);
73
    procedure Properties1Click(Sender: TObject);
73 daniel-mar 74
    procedure IdentificationsPopupMenuPopup(Sender: TObject);
68 daniel-mar 75
    procedure CopyTaskDefinitionExample1Click(Sender: TObject);
80 daniel-mar 76
    procedure ListViewCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer);
68 daniel-mar 77
    procedure Button3Click(Sender: TObject);
73 daniel-mar 78
    procedure LoadedPluginsPopupMenuPopup(Sender: TObject);
79
    procedure MenuItem1Click(Sender: TObject);
82 daniel-mar 80
    procedure FormCreate(Sender: TObject);
68 daniel-mar 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;
81 daniel-mar 90
  public
91
    procedure Run;
68 daniel-mar 92
  end;
93
 
94
var
95
  UD2MainForm: TUD2MainForm;
96
 
97
implementation
98
 
99
{$R *.dfm}
100
 
101
uses
69 daniel-mar 102
  ShellAPI, Clipbrd, Math, AlphaNumSort, UD2_Utils, UD2_TaskProperties;
68 daniel-mar 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
81 daniel-mar 132
  if (ParamCount >= 1) and not CheckBoolParam(1, 'C') then
68 daniel-mar 133
  begin
134
    if FileExists(ParamStr(1)) then
135
    begin
136
      result := ParamStr(1);
137
    end
138
    else
139
    begin
73 daniel-mar 140
      ExitCode := EXITCODE_INI_NOT_FOUND;
68 daniel-mar 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
73 daniel-mar 179
  TasksListView.Clear;
68 daniel-mar 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
 
73 daniel-mar 191
      TasksListView.AddItem(sl.Values[ShortTaskName], TObject(Obj));
68 daniel-mar 192
 
193
      iconString := ud2.ReadMetatagString(ShortTaskName, TagIcon, '');
194
      if iconString <> '' then
195
      begin
73 daniel-mar 196
        iconIndex := AddIconRecToImageList(SplitIconString(iconString), TasksImageList);
68 daniel-mar 197
        if iconIndex <> -1 then
198
        begin
73 daniel-mar 199
          TasksListView.Items.Item[TasksListView.Items.Count-1].ImageIndex := iconIndex;
68 daniel-mar 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);
73 daniel-mar 221
    ExitCode := EXITCODE_TASK_NOT_EXISTS;
68 daniel-mar 222
    Exit;
223
  end;
224
 
225
  slCmds := TStringList.Create;
226
  try
227
    ud2.GetCommandList(ShortTaskName, slCmds);
228
 
81 daniel-mar 229
    if (slCmds.Count = 0) and ud2.ReadMetatagBool(ShortTaskName, TagWarnIfNothingMatches, DefaultWarnIfNothingMatches) then
68 daniel-mar 230
    begin
231
      MessageDlg(LNG_NOTHING_MATCHES, mtWarning, [mbOK], 0);
81 daniel-mar 232
      ExitCode := EXITCODE_TASK_NOTHING_MATCHES;
68 daniel-mar 233
    end;
234
 
235
    for i := 0 to slCmds.Count-1 do
236
    begin
237
      cmd := slCmds.Strings[i];
238
      if cmd = '' then continue;
81 daniel-mar 239
      UD2_RunCMD(cmd, SW_NORMAL); // Idea: Let SW_NORMAL be configurable by the user?
68 daniel-mar 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;
73 daniel-mar 251
  for i := 0 to TasksListView.Items.Count-1 do
68 daniel-mar 252
  begin
73 daniel-mar 253
    TUD2ListViewEntry(TasksListView.Items.Item[i].Data).Free;
68 daniel-mar 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
73 daniel-mar 273
  IdentificationsListView.Clear;
68 daniel-mar 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;
73 daniel-mar 280
      with IdentificationsListView.Items.Add do
68 daniel-mar 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
 
73 daniel-mar 290
  for i := 0 to IdentificationsListView.Columns.Count-1 do
68 daniel-mar 291
  begin
73 daniel-mar 292
    IdentificationsListView.Columns.Items[i].Width := LVSCW_AUTOSIZE_USEHEADER;
68 daniel-mar 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;
69 daniel-mar 326
resourcestring
327
  LNG_MS = '%dms';
68 daniel-mar 328
var
329
  i: integer;
330
  pl: TUD2Plugin;
331
begin
73 daniel-mar 332
  LoadedPluginsListView.Clear;
68 daniel-mar 333
  for i := 0 to ud2.LoadedPlugins.Count-1 do
334
  begin
335
    pl := ud2.LoadedPlugins.Items[i] as TUD2Plugin;
73 daniel-mar 336
    with LoadedPluginsListView.Items.Add do
68 daniel-mar 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);
70 daniel-mar 343
      SubItems.Add(IntToStr(pl.DetectedIdentifications.Count));
69 daniel-mar 344
      SubItems.Add(Format(LNG_MS, [Max(1,pl.time)])); // at least show 1ms, otherwise it would be unloggical
70 daniel-mar 345
      SubItems.Add(pl.IdentificationProcedureStatusCodeDescribed);
68 daniel-mar 346
      SubItems.Add(pl.PluginGUIDString);
347
    end;
348
  end;
349
 
73 daniel-mar 350
  for i := 0 to LoadedPluginsListView.Columns.Count-1 do
68 daniel-mar 351
  begin
73 daniel-mar 352
    LoadedPluginsListView.Columns.Items[i].Width := LVSCW_AUTOSIZE_USEHEADER;
68 daniel-mar 353
  end;
354
end;
355
 
73 daniel-mar 356
procedure TUD2MainForm.TasksListViewDblClick(Sender: TObject);
68 daniel-mar 357
var
358
  obj: TUD2ListViewEntry;
359
begin
73 daniel-mar 360
  if TasksListView.ItemIndex = -1 then exit;
361
  obj := TUD2ListViewEntry(TasksListView.Selected.Data);
68 daniel-mar 362
  DoRun(obj.ShortTaskName);
363
  if obj.CloseAfterLaunching then Close;
364
end;
365
 
73 daniel-mar 366
procedure TUD2MainForm.TasksListViewKeyPress(Sender: TObject; var Key: Char);
68 daniel-mar 367
begin
368
  if Key = #13 then
369
  begin
73 daniel-mar 370
    TasksListViewDblClick(Sender);
68 daniel-mar 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
 
73 daniel-mar 399
procedure TUD2MainForm.TasksPopupMenuPopup(Sender: TObject);
68 daniel-mar 400
begin
73 daniel-mar 401
  Run1.Enabled := TasksListView.ItemIndex <> -1;
402
  Properties1.Enabled := TasksListView.ItemIndex <> -1;
68 daniel-mar 403
end;
404
 
405
procedure TUD2MainForm.Run1Click(Sender: TObject);
406
begin
73 daniel-mar 407
  TasksListViewDblClick(Sender);
68 daniel-mar 408
end;
409
 
410
procedure TUD2MainForm.Properties1Click(Sender: TObject);
411
var
412
  obj: TUD2ListViewEntry;
413
begin
73 daniel-mar 414
  if TasksListView.ItemIndex = -1 then exit;
415
  obj := TUD2ListViewEntry(TasksListView.Selected.Data);
68 daniel-mar 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
 
73 daniel-mar 423
procedure TUD2MainForm.IdentificationsPopupMenuPopup(Sender: TObject);
68 daniel-mar 424
begin
73 daniel-mar 425
  CopyTaskDefinitionExample1.Enabled := IdentificationsListView.ItemIndex <> -1;
68 daniel-mar 426
end;
427
 
428
procedure TUD2MainForm.CopyTaskDefinitionExample1Click(Sender: TObject);
429
var
430
  s: string;
431
begin
73 daniel-mar 432
  s := '; '+IdentificationsListView.Selected.Caption+#13#10+
433
       IdentificationsListView.Selected.SubItems[0] + ':' + IdentificationsListView.Selected.SubItems[1] + '=calc.exe'+#13#10+
68 daniel-mar 434
       #13#10+
435
       '; Alternatively:'+#13#10+
73 daniel-mar 436
       IdentificationsListView.Selected.SubItems[2] + ':' + IdentificationsListView.Selected.SubItems[1] + '=calc.exe'+#13#10;
68 daniel-mar 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
69 daniel-mar 448
    Compare := AlphaNumCompare(Item1.Caption, Item2.Caption);
68 daniel-mar 449
  end
450
  else
451
  begin
69 daniel-mar 452
    Compare := AlphaNumCompare(Item1.SubItems[ListView.CurSortedColumn-1],
453
                               Item2.SubItems[ListView.CurSortedColumn-1]);
68 daniel-mar 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
 
73 daniel-mar 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
80 daniel-mar 472
  s := '; ' + LoadedPluginsListView.Selected.SubItems.Strings[6];
73 daniel-mar 473
  Clipboard.AsText := s;
474
end;
475
 
81 daniel-mar 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
 
82 daniel-mar 506
  ud2.HandlePluginDir('',        '*.udp');
507
  ud2.HandlePluginDir('Plugins', '*.udp');
81 daniel-mar 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
 
82 daniel-mar 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
 
68 daniel-mar 554
end.