home *** CD-ROM | disk | FTP | other *** search
/ PC Administrator / spravce.iso / StartRight / source / UnitItemManager.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-10-26  |  18.2 KB  |  657 lines

  1. unit UnitItemManager;
  2. {
  3.     Purpose:
  4.         Create one centralized location where items
  5.         are Excluded/Disabled/Included. PPP
  6.  
  7.     Updates:
  8.         Items that are excluded will be removed from disabled lists
  9.         (They can be both excluded and disabled because of the AutoExcluding)
  10.  
  11.     Notes:
  12.         When an Item is removed from a sorted list, the sorted list
  13.         must be recreated to keep it contiguous.
  14. }
  15.  
  16. interface
  17.  
  18. uses Registry;
  19.  
  20. type TItemManager = class(TObject)
  21.     private
  22.         r : TRegistry;
  23.  
  24.         procedure AddToRunkeySortItems(value : string);
  25.         procedure AddToStartupfolderItem(filename : string);
  26.         procedure AddItem(key : string; itemdata : string);
  27.         procedure DeleteStartupSortItem(filename : string);
  28.  
  29.         procedure MoveFile(FullName, ToPath : string);
  30.     public
  31.         constructor Create;
  32.         destructor Destroy; override;
  33.         procedure AutoExcludeRunkeyItems;
  34.         procedure AutoExcludeStartupItems;
  35.  
  36.         procedure DisableRunkeyItem(value : string);
  37.         procedure DisableStartupItem(filename : string);
  38.  
  39.         procedure ExcludeRunkeyItem(value : string);
  40.         procedure ExcludeStartupItem(shortcutname : string);
  41.  
  42.         procedure IncludeRunkeyItem(value : string);
  43.         procedure IncludeStartupItem(filename : string);
  44.  
  45.         procedure EnableRunkeyItem(value : string);
  46.         procedure EnableStartupItem(filename : string);
  47.  
  48.         procedure CorrectExcludedShortcutItem(value : string);
  49.  
  50.         procedure ResortRunkeySortItems;
  51.         procedure ResortStartupSortItems;
  52.  
  53.  
  54. end;
  55.  
  56. var ItemManager : TItemManager;
  57.  
  58. {////////////////////}
  59. {//}implementation{//}
  60. {////////////////////}
  61.  
  62. uses Classes, Windows, UnitMyKeys, StrUtils, SysUtils, ShellAPI, ShlObj,
  63.     UnitFrmDummyRunner, Forms, UnitSpecialPaths;
  64.  
  65. constructor TItemManager.Create;
  66. begin
  67.     r := TRegistry.Create;
  68. end;
  69.  
  70. destructor TItemManager.Destroy;
  71. begin
  72.     r.Free;
  73.     inherited Destroy;
  74. end;
  75.  
  76.  
  77. procedure TItemManager.CorrectExcludedShortcutItem(value : string);
  78. var s, cs, als : string;
  79. begin
  80.     s := IncludeTrailingPathDelimiter(  SpecialPaths.GetStartupPath);
  81.     cs := IncludeTrailingPathDelimiter(  SpecialPaths.GetCommonStartupPath);
  82.     als := IncludeTrailingPathDelimiter(  SpecialPaths.GetAltStartupPath);
  83.  
  84.     r.RootKey := HKEY_LOCAL_MACHINE;
  85.     if r.OpenKey(SR_STARTUPEXCLUDE_KEY, false) then begin
  86.         if FileExists(s + value) then begin
  87.             r.WriteString(value, s + value);
  88.         end else if FileExists(cs + value) then begin
  89.             r.WriteString(value, cs + value);
  90.         end else if FileExists(als + value) then begin
  91.              r.WriteString(value, als + value);
  92.         end;
  93.         r.CloseKey;
  94.     end;
  95. end;
  96.  
  97. procedure TItemManager.DisableStartupItem(filename : string);
  98. var j, index : longint;
  99.     value : string;
  100. begin
  101.     // write the value to the disabled items
  102.     r.RootKey := HKEY_LOCAL_MACHINE;
  103.     if (r.OpenKey(SR_STARTUPDISABLE_KEY, true)) then begin
  104.         r.WriteString(ExtractFilename(filename), filename);
  105.         r.CloseKey;
  106.     end;
  107.  
  108.     // find the sorted item and remove it
  109.     r.RootKey := HKEY_LOCAL_MACHINE;
  110.     if (r.OpenKey(SR_STARTUPSORT_KEY, false)) then begin
  111.         try
  112.             index := r.ReadInteger(SR_SORTINDEX_VALUE);
  113.             for j := 0 to (index - 1) do begin
  114.                 value := r.ReadString(IntToStr(j));
  115.                 if lowercase(value) = lowercase(filename) then begin
  116.                     r.DeleteValue(IntToStr(j));
  117.                 end;
  118.             end;
  119.         finally
  120.             r.CloseKey;
  121.         end;
  122.     end;
  123.  
  124.     self.ResortStartupSortItems;
  125. end;
  126.  
  127.  
  128. procedure TItemManager.AutoExcludeStartupItems;
  129.     procedure ScanForFiles(path : string; files : TStringList);
  130.     var rec : TSearchRec;
  131.         r : integer;
  132.     begin
  133.         if (trim(path) <> '') then begin
  134.             path := IncludeTrailingPathDelimiter(path);
  135.  
  136.             r := findfirst(path + '*.*', faHidden  , rec);
  137.             while r = 0 do begin
  138.                 files.Add(rec.Name);
  139.  
  140.                 r := findnext(rec);
  141.             end;
  142.         end;
  143.     end;
  144. var
  145.    Startup, CommonStartup, AltStartup : string;
  146.    newExcludes, files : TStringList;
  147.    i, cnt : longint;
  148.    s : string;
  149.  
  150. begin
  151.     files := TStringList.Create;
  152.     newExcludes := TStringList.Create;
  153.  
  154.     //
  155.     // get all existing startup folder files
  156.     //
  157.  
  158.     Startup := SpecialPaths.GetStartupPath;
  159.     CommonStartup := SpecialPaths.GetCommonStartupPath;
  160.     AltStartup := SpecialPaths.GetAltStartupPath;
  161.  
  162.     ScanForFiles(Startup, files);
  163.     ScanForFiles(CommonStartup, files);
  164.     ScanForFiles(AltStartup, files);
  165.  
  166.     //
  167.     // search for my startup files for matches in the startupsort key
  168.     // exclude all matches (remove the startup sort item and add it to excluded list)
  169.     //
  170.     r.RootKey := HKEY_LOCAL_MACHINE;
  171.     if (r.OpenKey(SR_STARTUPSORT_KEY, false )) then begin
  172.         cnt := r.ReadInteger(SR_SORTINDEX_VALUE);
  173.         for i := 0 to (cnt - 1) do begin
  174.             s := ExtractFilename(r.ReadString(IntToStr(i)));
  175.             if (files.IndexOf(s) <> - 1) then begin
  176.                 r.DeleteValue(IntToStr(i));
  177.                 newExcludes.Add(s);
  178.             end;
  179.         end;
  180.  
  181.         r.closekey;
  182.     end;
  183.  
  184.  
  185.     for i := 0 to (newExcludes.Count - 1) do begin
  186.         ExcludeStartupItem(newExcludes.Strings[i]);
  187.     end;
  188.  
  189.     files.Free;
  190.     newExcludes.Free;
  191. end;
  192.  
  193.  
  194.  
  195. procedure TItemManager.ExcludeStartupItem(shortcutname : string);
  196. var src, startup : string;
  197. begin
  198.     //
  199.     // move file back to system's startup folder
  200.     // write to excluded list
  201.     // remove from disabled list
  202.     // (autoexcluded items that are also disabled don't work anyways) 
  203.     startup := SpecialPaths.GetCommonStartupPath;
  204.     src := SpecialPaths.GetStartRightStartup;
  205.  
  206.     MoveFile(src + ExtractFilename(shortcutname), Startup);
  207.  
  208.     r.RootKey := HKEY_LOCAL_MACHINE;
  209.     if (r.OpenKey(SR_STARTUPEXCLUDE_KEY, true)) then begin
  210.         r.WriteString(ExtractFilename(ShortcutName),
  211.             IncludeTrailingPathDelimiter(Startup) + ExtractFilename(Shortcutname));
  212.         r.CloseKey;
  213.     end;
  214.  
  215.     r.RootKey := HKEY_LOCAL_MACHINE;
  216.     if (r.OpenKey(SR_STARTUPDISABLE_KEY, false)) then begin
  217.         r.DeleteValue(ExtractFilename(shortcutname));
  218.         r.closekey;
  219.     end;
  220.  
  221.     self.DeleteStartupSortItem(shortcutname);
  222. end;
  223.  
  224. procedure TItemManager.AutoExcludeRunkeyItems;
  225. var winrun, myrun, exclude : TStringList;
  226.     i : longint;
  227.     s : string;
  228. begin
  229.     winrun := TStringList.Create;
  230.     myrun := TStringList.Create;
  231.     exclude  := TStringList.Create;
  232.  
  233.     //
  234.     // get both run keys and compare for matches
  235.     // on a match, delete from my run key and add to excluded items
  236.     //
  237.     r.RootKey := HKEY_LOCAL_MACHINE;
  238.     if (r.OpenKey(WINDOWS_RUN_KEY, false)) then begin
  239.         r.GetValueNames(winrun);
  240.         r.CloseKey;
  241.     end;
  242.  
  243.     r.RootKey := HKEY_LOCAL_MACHINE;
  244.     if (r.OpenKey(SR_RUN_KEY, false)) then begin
  245.         r.GetValueNames(myrun);
  246.  
  247.         for i := 0 to (myrun.Count - 1) do begin
  248.             s := myrun.Strings[i];
  249.             if (winrun.IndexOf(s) <> -1) then begin
  250.                 exclude.Add(s);
  251.                 r.DeleteValue(s);
  252.             end;
  253.         end;
  254.         r.CloseKey;
  255.     end;
  256.     self.ResortStartupSortItems;
  257.  
  258.     r.RootKey := HKEY_LOCAL_MACHINE;
  259.     if (r.OpenKey(SR_RUNEXCLUDE_KEY, false)) then begin
  260.         for i := 0 to (exclude.Count - 1) do begin
  261.             r.WriteString(exclude.Strings[i], SR_EXCLUDE_DATA);
  262.         end;
  263.         r.CloseKey;
  264.     end;
  265.  
  266.  
  267.     winrun.free;
  268.     myrun.Free;
  269.     exclude.free;
  270. end;
  271.  
  272.  
  273.  
  274. procedure TItemManager.ExcludeRunkeyItem(value : string);
  275. var data : string;
  276. begin
  277.     // add the items to the registry excluded list
  278.     // read the data from SR's run key and delete the value
  279.     // if was Disabled - it didn't work so remove it from disabled list
  280.     // add the value/data back to the Windows' Run key
  281.     r.RootKey := HKEY_LOCAL_MACHINE;
  282.     if (r.OpenKey(SR_RUNEXCLUDE_KEY, true)) then begin
  283.         r.WriteString(value, SR_EXCLUDE_DATA);
  284.         r.CloseKey;
  285.     end;
  286.  
  287.     r.RootKey := HKEY_LOCAL_MACHINE;
  288.     if (r.OpenKey(SR_RUN_KEY, false)) then begin
  289.         data := r.ReadString(value);
  290.         r.DeleteValue(value);
  291.         r.CloseKey;
  292.     end;
  293.     self.ResortRunkeySortItems;
  294.  
  295.     r.RootKey := HKEY_LOCAL_MACHINE;
  296.     if r.OpenKey(SR_RUNDISABLED_KEY, false) then begin
  297.         r.DeleteValue(value);
  298.         r.CloseKey;
  299.     end;
  300.  
  301.     r.RootKey := HKEY_LOCAL_MACHINE;
  302.     if (r.OpenKey(WINDOWS_RUN_KEY, false)) then begin
  303.         r.WriteString(value, data);
  304.         r.CloseKey;
  305.     end;
  306. end;
  307.  
  308. procedure TItemManager.DisableRunkeyItem(value : string);
  309. var i : longint;
  310.     runvalue, rundata : string;
  311.     SortValues : TStringList;
  312. begin
  313.     SortValues := TStringList.Create;
  314.  
  315.     // Delete the run key value
  316.     // [save the data for later]
  317.     r.RootKey := HKEY_LOCAL_MACHINE;
  318.     if (r.OpenKey(SR_RUN_KEY, false)) then begin
  319.         rundata := r.ReadString(value);
  320.         r.DeleteValue(value);
  321.         r.CloseKey;
  322.     end;
  323.  
  324.     // find all entries in the RunSort key and remove them
  325.     // [there should only be one key, but older versions might
  326.     // screw that up]
  327.     r.RootKey := HKEY_LOCAL_MACHINE;
  328.     if (r.OpenKey(SR_RUNSORT_KEY, false)) then begin
  329.         r.GetValueNames(SortValues);
  330.         SortValues.Delete(SortValues.IndexOf(SR_SORTINDEX_VALUE));
  331.  
  332.         for i := (SortValues.Count - 1) downto 0 do begin
  333.             RunValue := r.ReadString(SortValues.Strings[i]);
  334.             if RunValue = value then begin
  335.                 r.DeleteValue(SortValues.Strings[i]);
  336.             end;
  337.         end;
  338.         r.CloseKey;
  339.     end;
  340.  
  341.     // Add the entry into the RunDisabled key, so that it
  342.     // may be enabled at at future date
  343.     r.RootKey := HKEY_LOCAL_MACHINE;
  344.     if (r.OpenKey(SR_RUNDISABLED_KEY, true)) then begin
  345.         r.WriteString(value, rundata);
  346.         r.CloseKey;
  347.     end;
  348.  
  349.     // resort since we just screwed up the contiguos numbers
  350.     // in the sort key
  351.  
  352.     self.ResortRunkeySortItems;
  353.     SortValues.Free;
  354. end;
  355.  
  356.  
  357.  
  358.  
  359. procedure TItemManager.IncludeRunkeyItem(value : string);
  360. var rundata : string;
  361. begin
  362.     // Find the item in windows' run key
  363.     r.RootKey := HKEY_LOCAL_MACHINE;
  364.     if r.OpenKey(WINDOWS_RUN_KEY, false) then begin
  365.         rundata := r.ReadString(value);
  366.         r.CloseKey;
  367.     end;
  368.  
  369.     // Ignore if item doesn't exist
  370.     // write into my runkey
  371.     if (rundata <> '') then begin
  372.         r.RootKey := HKEY_LOCAL_MACHINE;
  373.         if r.OpenKey(SR_RUN_KEY, true) then begin
  374.             r.WriteString(value, rundata);
  375.             r.CloseKey;
  376.         end;
  377.         self.AddToRunkeySortItems(value);
  378.         self.ResortRunkeySortItems; {just to be sure}
  379.     end;
  380.  
  381.     // remove from my excluded list
  382.     r.RootKey := HKEY_LOCAL_MACHINE;
  383.     if r.OpenKey(SR_RUNEXCLUDE_KEY, false) then begin
  384.         r.DeleteValue(value);
  385.         r.CloseKey;
  386.     end;
  387. end;
  388. procedure TItemManager.IncludeStartupItem(filename : string);
  389. var dest : string;
  390. begin
  391.     // move the file back to the SR's startup folder
  392.     // remove the item from the exclusion list
  393.     dest := SpecialPaths.GetStartRightStartup;
  394.     if FileExists(filename) then begin
  395.         MoveFile(FileName, dest);
  396.     end;
  397.  
  398.     r.RootKey := HKEY_LOCAL_MACHINE;
  399.     if r.OpenKey(SR_STARTUPEXCLUDE_KEY, false) then begin
  400.         r.DeleteValue(ExtractFileName(filename));
  401.         r.CloseKey;
  402.     end;
  403.  
  404.     self.AddToStartupfolderItem(IncludeTrailingPathDelimiter(dest)
  405.         + ExtractFilename(filename));
  406. end;
  407.  
  408.  
  409. procedure TItemManager.EnableRunkeyItem(value : string);
  410. var rundata : string;
  411. begin
  412.     // Find the data in my disabled list
  413.     // and remove it
  414.     r.RootKey := HKEY_LOCAL_MACHINE;
  415.     if r.OpenKey(SR_RUNDISABLED_KEY, false) then begin
  416.         rundata := r.ReadString(value);
  417.         r.DeleteValue(value);
  418.         r.CloseKey;
  419.     end;
  420.  
  421.     // Ignore if item doesn't exist
  422.     // write into my runkey
  423.     if (rundata <> '') then begin
  424.         r.RootKey := HKEY_LOCAL_MACHINE;
  425.         if r.OpenKey(SR_RUN_KEY, false) then begin
  426.             r.WriteString(value, rundata);
  427.             r.CloseKey;
  428.         end;
  429.         self.AddToRunkeySortItems(value);
  430.         self.ResortRunkeySortItems; {just to be sure}
  431.     end;
  432. end;
  433.  
  434. procedure TItemManager.EnableStartupItem(filename : string);
  435. begin
  436.     // remove the disable key
  437.     r.RootKey := HKEY_LOCAL_MACHINE;
  438.     if (r.OpenKey(SR_STARTUPDISABLE_KEY, false)) then begin
  439.         r.DeleteValue(ExtractFilename(filename));
  440.         r.closekey;
  441.     end;
  442.  
  443.     self.AddToStartupfolderItem(filename);
  444. end;
  445.  
  446.  
  447. //====================================
  448. // Util methods
  449. //====================================
  450.  
  451.  
  452.  
  453.  
  454.  
  455. procedure TItemManager.ResortRunKeySortItems;
  456. var runvalues, values, data : TStringList;
  457.     sortdata : string;
  458.     i : longint;
  459. begin
  460.     values := TStringList.Create;
  461.     data := TStringList.Create;
  462.     runvalues := TStringList.Create;
  463.  
  464.     r.RootKey := HKEY_LOCAL_MACHINE;
  465.     if (r.OpenKey(SR_RUN_KEY, false)) then begin
  466.         r.GetValueNames(runvalues);
  467.         r.CloseKey;
  468.     end;
  469.  
  470.     //
  471.     // read the Startup sort data
  472.     // remove any invalid entries and the SortIndex value
  473.  
  474.     r.RootKey := HKEY_LOCAL_MACHINE;
  475.     if (r.OpenKey(SR_RUNSORT_KEY, false)) then begin
  476.         r.GetValueNames(values);
  477.         for i := (values.Count - 1) downto 0 do begin
  478.             if (values.Strings[i] = SR_SORTINDEX_VALUE) then begin
  479.                 values.Delete(i);
  480.                 CONTINUE;
  481.             end;
  482.  
  483.             {remove sort links to items no longer in the run key}
  484.             sortdata := r.ReadString(values.Strings[i]);
  485.             if (runvalues.IndexOf(sortdata) <> -1) then begin
  486.                 data.Insert(0, sortdata);
  487.             end else begin
  488.                 values.Delete(i);
  489.             end;
  490.         end;
  491.  
  492.         r.CloseKey;
  493.     end;
  494.  
  495.     r.RootKey := HKEY_LOCAL_MACHINE;
  496.     if (r.OpenKey(SR_HOME_KEY, false)) then begin
  497.         r.DeleteKey(SR_SUB_RUNSORT);
  498.         r.CreateKey(SR_SUB_RUNSORT);
  499.         r.CloseKey;
  500.     end;
  501.     r.RootKey := HKEY_LOCAL_MACHINE;
  502.     if (r.OpenKey(SR_RUNSORT_KEY, false)) then begin
  503.         for i := 0 to (data.Count - 1) do begin
  504.             r.WriteString(IntToStr(i), data.Strings[i]);
  505.         end;
  506.         r.WriteInteger(SR_SORTINDEX_VALUE, data.count);
  507.         r.CloseKey;
  508.     end;
  509.  
  510.     runvalues.Free;
  511.     values.Free;
  512.     data.Free;
  513. end;
  514.  
  515.  
  516. procedure TItemManager.ResortStartupSortItems;
  517. begin
  518.     self.DeleteStartupSortItem('');
  519. end;
  520.  
  521.  
  522.  
  523.  
  524. //================================
  525. // Private Implemenation
  526. //================================
  527.  
  528. procedure TItemManager.AddItem(key : string; itemdata : string);
  529. var i, sortIndex : integer;
  530.     values, data : TStringList;
  531. begin
  532.     values := TStringList.Create;
  533.     data := TStringList.Create;
  534.  
  535.     r.RootKey := HKEY_LOCAL_MACHINE;
  536.     if (r.OpenKey(KEY, true)) then begin
  537.         // read current list of items / so duplicates
  538.         // can be ignored
  539.         r.GetValueNames(values);
  540.         i := values.IndexOf(SR_SORTINDEX_VALUE);
  541.         if (i <> -1) then values.Delete(i);
  542.         for i := 0 to (values.count - 1) do begin
  543.             data.Add(r.ReadString(values[i]));
  544.         end;
  545.  
  546.  
  547.         // read the sort index (default if doesn't exist)
  548.         // write new entry at end of list
  549.         // increment the sort index
  550.         if (not r.ValueExists(SR_SORTINDEX_VALUE)) then begin
  551.             sortIndex := 0;
  552.         end else begin
  553.             sortIndex := r.ReadInteger(SR_SORTINDEX_VALUE);
  554.         end;
  555.  
  556.         {Add only if doesn't already exist}
  557.         if (data.IndexOf(itemdata) = -1) then begin
  558.             r.WriteString(IntToStr(sortIndex), itemdata);
  559.             r.WriteInteger(SR_SORTINDEX_VALUE, sortIndex + 1);
  560.         end;
  561.         r.CloseKey;
  562.     end;
  563.  
  564.     values.Free;
  565.     data.Free;
  566. end;
  567.  
  568. procedure TItemManager.AddToStartupfolderItem(filename : string);
  569. begin
  570.     self.AddItem(SR_STARTUPSORT_KEY, filename);
  571. end;
  572.  
  573. procedure TItemManager.AddToRunkeySortItems(value : string);
  574. begin
  575.     self.AddItem(SR_RUNSORT_KEY, value);
  576. end;
  577.  
  578.  
  579. procedure TItemManager.DeleteStartupSortItem(filename : string);
  580. var values, data : TStringList;
  581.     i : integer;
  582.     s : string;
  583. begin
  584.     //
  585.     values := TStringList.Create();
  586.     data := TStringList.Create();
  587.  
  588.     //
  589.     // extract the existing values/data
  590.     // [minus the sort index]
  591.     // [delete any entries matching filename]
  592.     r.RootKey := HKEY_LOCAL_MACHINE;
  593.     if (r.OpenKey(SR_STARTUPSORT_KEY, false)) then begin
  594.         r.GetValueNames(values);
  595.         values.Delete(values.IndexOf(SR_SORTINDEX_VALUE));
  596.  
  597.         for i := 0 to values.Count - 1 do begin
  598.             s := r.ReadString(values[i]);
  599.             if (filename <> s) or (filename = '') then begin
  600.                 data.Add(s);
  601.             end else begin
  602.                 values.Delete(i);
  603.             end;
  604.         end;
  605.  
  606.         r.CloseKey;
  607.     end;
  608.  
  609.     //
  610.     // delete existing and recreate
  611.     r.RootKey := HKEY_LOCAL_MACHINE;
  612.     if (r.OpenKey(SR_HOME_KEY, false)) then begin
  613.         r.DeleteKey(SR_SUB_STARTUPSORT);
  614.         r.CreateKey(SR_SUB_STARTUPSORT);
  615.         r.CloseKey;
  616.     end;
  617.  
  618.     r.RootKey := HKEY_LOCAL_MACHINE;
  619.     if (r.OpenKey(SR_STARTUPSORT_KEY, false)) then begin
  620.         for i := 0 to (values.Count - 1) do begin
  621.             r.WriteString(values[i], data[i]);
  622.         end;
  623.         r.WriteInteger(SR_SORTINDEX_VALUE, values.count);
  624.         r.CloseKey;
  625.     end;
  626.  
  627.     values.free;
  628.     data.Free;
  629. end;
  630.  
  631.  
  632. procedure TItemManager.MoveFile(FullName, ToPath : string);
  633. var exeName : string;
  634.     dest : string;
  635. begin
  636.     exeName := ExtractFileName(FullName);
  637.  
  638.     dest := IncludeTrailingPathDelimiter(ToPath) + exeName;
  639.     if FileExists( dest ) then begin
  640.        DeleteFile( dest );
  641.     end;
  642.     if (lowercase(dest) <> lowercase(fullname)) then begin
  643.         if CopyFile(PChar(FullName), PChar(Dest), true) then begin
  644.             DeleteFile(FullName);
  645.         end;
  646.     end;
  647. end;
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654. initialization
  655.     ItemManager := TItemManager.Create();
  656. end.
  657.