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

  1. unit UnitStartupMover;
  2. {
  3.     Purpose:
  4.         Move all unexluded items into StartRight
  5.         or
  6.         Restore all items back to the system
  7.  
  8.     Updates:
  9.         Using the new ItemManager for all Exclude/Include/Disable
  10.         operations
  11.  
  12.     Notes:
  13.         Moving runkeys installs StartRight in the system's Run key
  14.         Restoring runkeys removes StartRight from the system's Run key
  15.  
  16. }
  17.  
  18. interface
  19.  
  20. uses Windows, Registry, SysUtils, StrUtils, TLHelp32,
  21.     INIFiles, Contnrs, ShlObj, ShellAPI,
  22.     Forms {for Application object},
  23.     Classes {For TString objects},
  24.     dialogs, {showmessage debuggin}
  25.     UnitMyKeys;
  26.  
  27.  
  28.  
  29. //
  30. //
  31. //
  32.  
  33. type TRunkeyItem = Class(TObject)
  34.     RunKey : string;
  35.     RunValue : string;
  36.     RunEXE : string;
  37.     RunProcID : cardinal;
  38.     public
  39.         function ToString() : string;
  40. end;
  41.  
  42. type TStartupFolderItem = Class(Tobject)
  43.     FullName : String;
  44. end;
  45.  
  46.  
  47. type TStartupMover = class(TObject)
  48.     private
  49.         h : THandle;
  50.         r : TRegistry;
  51.  
  52.         tsVals : THashedStringList;
  53.         tsKeys : THashedStringList;
  54.         tsEXEs : THashedStringList;
  55.  
  56.         tsProc : THashedStringList;
  57.         tsProcID : THashedStringList;
  58.  
  59.         RunkeyList : TObjectList;
  60.         StartupFolderList : TObjectList;
  61.  
  62.         HasNewItems : boolean;
  63.  
  64.  
  65.         procedure GetRunkeyData;
  66.         procedure GetStartupFolderData;
  67.         procedure GenerateRunkeyList;
  68.         procedure GenerateStartupFolderList;
  69.         procedure SetupSelfToRun;
  70.  
  71.     public
  72.         constructor Create(handle : THandle);
  73.         destructor Destroy(); override;
  74.  
  75.  
  76.         function GetRunkeyItemsCount : cardinal;
  77.         function GetRunkeyItem(index : cardinal) : TRunkeyItem;
  78.         function GetStartupFolderItemsCount : cardinal;
  79.         function GetStartupFolderItem(index : cardinal) : TStartupFolderItem;
  80.  
  81.         procedure MoveRunKeyItems;
  82.         procedure MoveStartupFolderItems;
  83.  
  84.  
  85.         procedure RestoreRunKeyItems;
  86.         procedure RestoreStartupFolderItems;
  87.  
  88.         function GetHasNewItems : boolean;
  89. end;
  90.  
  91.  
  92. {////////////////////}
  93. {//}implementation
  94.  
  95. uses UnitSpecialPaths, UnitItemManager;{//}
  96. {////////////////////}
  97.  
  98.  
  99. function TRunkeyItem.ToString() : string;
  100. begin
  101.     result := self.RunKey + '|' + self.RunValue + '|' + self.RunEXE + '|' + IntToStr(self.RunProcID);
  102. end;
  103.  
  104.  
  105.  
  106. ////////////////////////////////
  107. // Public Interface
  108. ////////////////////////////////
  109.  
  110. function TStartupMover.GetHasNewItems : boolean;
  111. begin
  112.     result := self.HasNewItems; 
  113. end;
  114.  
  115. constructor TStartupMover.Create(handle : THandle);
  116. begin
  117.     h := handle;
  118.     r := TRegistry.Create();
  119.  
  120.     tsKeys := THashedStringList.Create();
  121.     tsVals := THashedStringList.Create();
  122.     tsEXEs := THashedStringList.Create();
  123.  
  124.     tsProc :=  THashedStringList.Create();
  125.     tsProcID := THashedStringList.Create();
  126.  
  127.     RunkeyList := TObjectList.Create();
  128.     StartupFolderList := TObjectList.Create();
  129.  
  130.     //
  131.     // Purpose: Gather everything needed to create the RunkeyList
  132.     //          and the StartupFolderList
  133.     //
  134.  
  135.     self.HasNewItems := false;
  136.     self.GetRunkeyData;
  137.     self.GetStartupFolderData;
  138.     self.GenerateRunkeyList;
  139.     self.GenerateStartupFolderList;
  140.  
  141.     HasNewItems := false;
  142. end;
  143.  
  144. destructor TStartupMover.Destroy();
  145. begin
  146.     r.Free;
  147.  
  148.     tsKeys.Free;
  149.     tsVals.Free;
  150.     tsEXEs.Free;
  151.  
  152.     tsProc.Free;
  153.     tsProcID.Free;
  154.  
  155.     RunkeyList.Clear;
  156.     RunkeyList.Free;
  157.  
  158.     StartupFolderList.Clear;
  159.     StartupFolderList.Free;
  160.  
  161.     inherited destroy;
  162. end;
  163.  
  164.  
  165. //--------------------------------------------------------------
  166. // Enumerate items in the RunkeyList/StartupFolderList
  167. //--------------------------------------------------------------
  168. function TStartupMover.GetRunkeyItemsCount : cardinal;
  169. begin
  170.     result := RunkeyList.Count;
  171. end;
  172. function TStartupMover.GetRunkeyItem(index : cardinal) : TRunkeyItem;
  173. begin
  174.     result := TRunkeyItem( RunkeyList.items[index] );
  175. end;
  176.  
  177. function TStartupMover.GetStartupFolderItemsCount : cardinal;
  178. begin
  179.     result := StartupFolderList.Count;
  180. end;
  181. function TStartupMover.GetStartupFolderItem(index : cardinal) : TStartupFolderItem;
  182. begin
  183.     result := TStartupFolderItem( StartupFolderList.items[index] );
  184. end;
  185.  
  186.  
  187. //--------------------------------------------------------------
  188. // Move(RunKey/StartupFolder)Items
  189. //
  190. // RunKey
  191. // - Move un-exluded keys to StartRight's runkey
  192. // - create a sort index for new items
  193. // - update locale RunKey info (since this changes it)
  194. //--------------------------------------------------------------
  195. procedure TStartupMover.MoveRunKeyItems;
  196.     procedure DeleteOtherRunData(excluded : THashedStringList);
  197.     var i : integer;
  198.     begin
  199.         if (r.OpenKey(WINDOWS_RUN_KEY, false)) then begin
  200.             for i := 0 to (tsKeys.Count - 1) do begin
  201.                 if (tsKeys[i] <> SR_STARTRIGHT_VALUE) and
  202.                     (excluded.IndexOf(tsKeys[i]) = -1 ) then begin
  203.                     r.DeleteValue(tsKeys[i]);
  204.                 end;
  205.             end;
  206.             r.CloseKey;
  207.         end;
  208.     end;
  209.  
  210. var i : integer;
  211.     sti : TRunkeyItem;
  212.     excluded : THashedStringList;
  213.     newvalues : THashedStringList;
  214.  
  215. begin
  216.     excluded := THashedStringList.Create();
  217.     newvalues := THashedStringList.Create();
  218.     //
  219.     // read excluded key names
  220.     // [exclude StartRight always]
  221.     r.RootKey := HKEY_LOCAL_MACHINE;
  222.     if (r.OpenKey(SR_RUNEXCLUDE_KEY, false)) then begin
  223.         r.GetValueNames(excluded);
  224.         r.CloseKey;
  225.     end;
  226.     excluded.Add(SR_STARTRIGHT_VALUE);
  227.  
  228.     //
  229.     // Copy all keys, except for those that are excluded (and ME!)
  230.     // Write all new items into the registry
  231.     for i := 0 to (RunkeyList.Count - 1) do begin
  232.         sti := TRunkeyItem( RunkeyList.Items[i] );
  233.  
  234.         if (excluded.IndexOf(sti.RunKey ) = -1) then begin
  235.             ItemManager.IncludeRunkeyItem(sti.Runkey);
  236.             newvalues.Add(sti.RunKey);
  237.         end;
  238.     end;
  239.  
  240.     r.RootKey := HKEY_LOCAL_MACHINE;
  241.     if (r.OpenKey(SR_HOME_KEY, false)) then begin
  242.         r.DeleteKey(SR_SUB_RUNNEWITEMS);
  243.         r.CloseKey;
  244.     end;
  245.     r.RootKey := HKEY_LOCAL_MACHINE;
  246.     if (r.OpenKey(SR_RUNNEWITEMS_KEY, true)) then begin
  247.         for i := 0 to (newvalues.Count - 1) do begin
  248.             r.WriteString(newvalues.Strings[i], 'NEW');
  249.         end;
  250.         r.CloseKey;
  251.     end;
  252.     self.HasNewItems := self.HasNewItems or (newvalues.Count > 0);
  253.  
  254.  
  255.     //
  256.     // delete the other run data
  257.     //
  258.     r.RootKey := HKEY_LOCAL_MACHINE;
  259.     DeleteOtherRunData(excluded);
  260.  
  261.     r.RootKey := HKEY_CURRENT_USER;
  262.     DeleteOtherRunData(excluded);
  263.  
  264.     self.SetupSelfToRun;
  265.     self.GetRunkeyData;
  266.     self.GenerateRunkeyList;
  267.  
  268.  
  269.     excluded.Free;
  270.     newvalues.free;
  271. end;
  272.  
  273. procedure TStartupMover.MoveStartupFolderItems;
  274. var si : TStartupFolderItem;
  275.     i : integer;
  276.     dest, s : string;
  277.  
  278.     excluded : THashedStringList;
  279.     disabled, newvalues : THashedStringList;
  280. begin
  281.     //
  282.     // build my startup path
  283.     //
  284.     excluded := THashedStringList.Create();
  285.     disabled := THashedStringList.Create();
  286.     newvalues := THashedStringList.Create();
  287.  
  288.     dest := SpecialPaths.GetStartRightStartup ;
  289.     if not DirectoryExists(dest) then begin
  290.         MkDir(dest);
  291.     end;
  292.  
  293.  
  294.     //
  295.     // get excluded/disabled shortcuts
  296.     //
  297.     r.RootKey := HKEY_LOCAL_MACHINE;
  298.     if (r.OpenKey(SR_STARTUPEXCLUDE_KEY, false)) then begin
  299.         r.GetValueNames(excluded);
  300.         r.CloseKey;
  301.     end;
  302.     r.RootKey := HKEY_LOCAL_MACHINE;
  303.     if (r.OpenKey(SR_STARTUPDISABLE_KEY, false)) then begin
  304.         r.GetValueNames(disabled);
  305.         r.CloseKey;
  306.     end;
  307.  
  308.  
  309.  
  310.     //
  311.     // move everything excepts what's excluded
  312.     // don't add an entry to the startupsort key
  313.     // record new items
  314.     for i := 0 to StartupFolderList.Count - 1 do begin
  315.         si := TStartupFolderItem( StartupFolderList.items[i] );
  316.         s := ExtractFilename(si.FullName);
  317.         if (excluded.IndexOf(s) = -1)
  318.             and (disabled.indexOf(s) = -1) then begin
  319.             ItemManager.IncludeStartupItem(si.FullName);
  320.             newvalues.Add(si.fullname);
  321.         end;
  322.     end;
  323.     // record the new items
  324.     r.RootKey := HKEY_LOCAL_MACHINE;
  325.     if (r.OpenKey(SR_HOME_KEY, false)) then begin
  326.         r.DeleteKey(SR_SUB_STARTUPNEW);
  327.         r.CreateKey(SR_SUB_STARTUPNEW);
  328.         r.CloseKey;
  329.     end;
  330.  
  331.     r.RootKey := HKEY_LOCAL_MACHINE;
  332.     if (r.OpenKey(SR_STARTUPNEW_KEY, true)) then begin
  333.         for i := 0 to newvalues.Count - 1 do begin
  334.             s := SpecialPaths.GetStartRightStartup;
  335.             r.WriteString(ExtractFilename(newvalues[i]), s + ExtractFilename(newvalues[i]));
  336.         end;
  337.         r.CloseKey;
  338.     end;
  339.     self.HasNewItems := self.HasNewItems or (newvalues.Count > 0);
  340.  
  341.  
  342.     excluded.Free;
  343.     disabled.Free;
  344.  
  345.     self.GetStartupFolderData;
  346.     self.GenerateStartupFolderList;
  347. end;
  348.  
  349.  
  350. procedure TStartupMover.RestoreRunKeyItems;
  351. var sl, sl2 : TStringList;
  352.     i : integer;
  353.     s : string;
  354. begin
  355.     //
  356.     // read the shadow copy
  357.     //
  358.     sl2 := TStringList.Create();
  359.     sl := TStringList.Create();
  360.  
  361.     r.RootKey := HKEY_LOCAL_MACHINE;
  362.     if r.OpenKey(SR_RUN_KEY, false) then begin
  363.         r.GetValueNames(sl);
  364.  
  365.         for i := 0 to (sl.Count - 1) do begin
  366.             try
  367.                s := r.ReadString(sl[i]);
  368.                sl2.add(s);
  369.             finally
  370.             end;
  371.         end;
  372.  
  373.         r.CloseKey;
  374.     end;
  375.  
  376.     //
  377.     // write it back to the system's RUN key
  378.     // Remove StartRight from the system'm run key
  379.     //
  380.     r.RootKey := HKEY_LOCAL_MACHINE;
  381.     if (r.OpenKey(WINDOWS_RUN_KEY, false)) then begin
  382.         for i := 0 to (sl2.count - 1) do begin
  383.             r.WriteString(sl[i], sl2[i]);
  384.         end;
  385.  
  386.         r.DeleteValue(SR_STARTRIGHT_VALUE);
  387.         r.CloseKey;
  388.     end;
  389.  
  390.     //
  391.     // Remove the shadowed data
  392.     // remove sort info
  393.     //
  394.     r.RootKey := HKEY_LOCAL_MACHINE;
  395.     if (r.OpenKey(SR_HOME_KEY, false )) then begin
  396.         r.DeleteKey(SR_SUB_RUN);
  397.         r.DeleteKey(SR_SUB_RUNSORT);
  398.         r.CloseKey;
  399.     end;
  400.  
  401.     sl.free;
  402.     sl2.free;
  403.  
  404.     self.GetRunkeyData;
  405.     self.GenerateRunkeyList;
  406. end;
  407.  
  408. procedure TStartupMover.RestoreStartupFolderItems;
  409.     procedure MoveFile(FullName, ToPath : string);
  410.     var exeName : string;
  411.         dest : string;
  412.     begin
  413.         exeName := ExtractFileName(FullName);
  414.  
  415.         dest := IncludeTrailingPathDelimiter(ToPath) + exeName;
  416.         if FileExists( dest ) then begin
  417.            DeleteFile( dest );
  418.         end;
  419.  
  420.         if CopyFile(PChar(FullName), PChar(Dest), true) then begin
  421.             DeleteFile(FullName);
  422.         end;
  423.     end;
  424. var src, startup : string;
  425.     rec : TSearchRec;
  426.     rz : integer;
  427.  
  428.  
  429. begin
  430.     //
  431.     // get destination Startup folder
  432.     //
  433.     Startup := SpecialPaths.GetCommonStartupPath;
  434.  
  435.     src := SpecialPaths.GetStartRightStartup;
  436.  
  437.     rz := FindFirst(src + '*.*', faHidden, rec);
  438.     while (rz = 0) do begin
  439.         MoveFile(src + rec.name, Startup);
  440.  
  441.         rz := FindNext(rec);
  442.     end;
  443.  
  444.     //
  445.     // delete the startup sort key
  446.     //
  447.     r.RootKey := HKEY_LOCAL_MACHINE;
  448.     if (r.OpenKey(SR_HOME_KEY, false)) then begin
  449.         r.DeleteKey(SR_SUB_STARTUPSORT);
  450.         r.CloseKey;
  451.     end;
  452.     
  453.  
  454.     self.GetStartupFolderData;
  455.     self.GenerateStartupFolderList;
  456. end;
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464. /////////////////////////////////////////////////////////////////////////////
  465. // Private Implemenation
  466. /////////////////////////////////////////////////////////////////////////////
  467.  
  468.  
  469.  
  470. procedure TStartupMover.SetupSelfToRun;
  471. begin
  472.     r.RootKey := HKEY_LOCAL_MACHINE;
  473.     if (r.openkey(WINDOWS_RUN_KEY, false)) then begin
  474.         r.WriteString(SR_STARTRIGHT_VALUE, '"' +Application.ExeName + '" -go ' );
  475.         r.CloseKey;
  476.     end;
  477. end;
  478.  
  479.  
  480.  
  481. //---------------------------------------------------------
  482. // Gather all the data from the Run key in the registry
  483. // (that's a String)
  484. //---------------------------------------------------------
  485. procedure TStartupMover.GetRunkeyData;
  486.     function GetEXEFromRunValue(value : string) : string;
  487.     var i : integer;
  488.     begin
  489.         value := lowercase(value);
  490.         i := pos('.exe', value);
  491.         result := '';
  492.  
  493.         if (i > 0) then begin
  494.             result := LeftStr(value, i + 3);
  495.  
  496.             if leftstr(result,1) ='"' then
  497.                 result := RightStr(result, length(result) - 1);
  498.  
  499.             result := UPPERCASE(ExtractFileName(result));
  500.         end;
  501.     end;
  502.  
  503.     procedure ExtractRunkeyData();
  504.     var i : integer;
  505.         s : string;
  506.         sl : TStringList;
  507.     begin
  508.         sl := TStringList.Create();
  509.         if (r.OpenKey(WINDOWS_RUN_KEY, false)) then begin
  510.             r.GetValueNames(sl);
  511.  
  512.             // skip any values that may be blanks
  513.             for i := 0 to (sl.Count - 1) do begin
  514.                 if (trim(sl.Strings[i]) = '') then continue;
  515.  
  516.                 try
  517.                     s := r.ReadString( sl.Strings[i] );
  518.                     if (s <> '') then begin
  519.                         tsKeys.Add(sl.Strings[i]);
  520.                         tsVals.add(s);
  521.                         tsEXEs.Add( GetEXEFromRunValue(s) );
  522.                     end;
  523.                 finally
  524.                 end;
  525.             end;
  526.  
  527.             r.CloseKey;
  528.         end;
  529.         sl.free;
  530.     end;
  531. var f : string;
  532. begin
  533.     tsKeys.Clear;
  534.     tsVals.Clear;
  535.     tsEXEs.Clear;
  536.  
  537.     r.RootKey := HKEY_LOCAL_MACHINE;
  538.     ExtractRunkeyData;
  539.  
  540.  
  541.     r.RootKey := HKEY_CURRENT_USER;
  542.  
  543.     // debug data
  544.     ExtractRunkeyData;
  545.     f := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
  546.     tsKeys.SaveToFile(f + 'keys.txt');
  547.     tsVals.SaveToFile(f + 'vals.txt');
  548.     tsEXEs.SaveToFile(f + 'exes.txt'); 
  549. end;
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556. //-------------------------------------------------------------------
  557. // Get the Process EXE & Process ID name from a current snapshot
  558. //-------------------------------------------------------------------
  559. procedure TStartupMover.GetStartupFolderData;
  560. var h : THandle;
  561.     b : longbool;
  562.     s : string;
  563.     pInfo : TProcessEntry32;
  564. begin
  565.     h := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  566.     if (h <> 0) then begin
  567.         pInfo.dwSize := sizeof(pInfo);
  568.         b := Process32First(h, pInfo);
  569.  
  570.         while b do begin
  571.             s := UPPERCASE(String(pInfo.szExeFile));
  572.             tsProc.Add( s );
  573.             tsProcID.Add( IntToStr(pInfo.th32ProcessID) );
  574.             b := Process32Next(h, pInfo);
  575.         end;
  576.  
  577.         CloseHandle(h);
  578.     end;
  579. end;
  580.  
  581.  
  582. //-----------------------------------------------------------------
  583. // Build(xxx)Info - compile all the gathered info into 2 lists
  584. //-----------------------------------------------------------------
  585.  
  586. procedure TStartupMover.GenerateRunkeyList;
  587. var sti : TRunkeyItem;
  588.     i : integer;
  589.     idx : integer;
  590. begin
  591.     RunkeyList.Clear;
  592.  
  593.     for i := 0 to tsKeys.Count - 1 do begin
  594.         sti := TRunkeyItem.Create();
  595.  
  596.         sti.RunKey := tsKeys[i];
  597.         sti.RunValue := tsVals[i];
  598.         sti.RunEXE := tsEXEs[i];
  599.         sti.RunProcID := 0;
  600.         idx := tsProc.IndexOf(sti.RunEXE);
  601.         if (idx <> -1) then begin
  602.             sti.RunProcID := StrToInt( tsProcID[i] );
  603.         end;
  604.  
  605.         RunkeyList.Add(sti);
  606.     end;
  607. end;
  608.  
  609. procedure TStartupMover.GenerateStartupFolderList;
  610.     procedure ScanForFiles(path : string);
  611.     var rec : TSearchRec;
  612.         r : integer;
  613.         si : TStartupFolderItem;
  614.     begin
  615.         if (trim(path) <> '') then begin
  616.             path := IncludeTrailingPathDelimiter(path);
  617.  
  618.             r := findfirst(path + '*.*', faHidden  , rec);
  619.             while r = 0 do begin
  620.                 si := TStartupFolderItem.Create();
  621.  
  622.                 si.FullName :=  path + rec.Name;
  623.                 StartupFolderList.Add(si);
  624.  
  625.                 r := findnext(rec);
  626.             end;
  627.         end;
  628.     end;
  629. var Startup, CommonStartup, AltStartup : string;
  630. begin
  631.     Startup := SpecialPaths.GetStartupPath;
  632.     CommonStartup := SpecialPaths.GetCommonStartupPath;
  633.     AltStartup := SpecialPaths.GetAltStartupPath;
  634.  
  635.  
  636.     StartupFolderList.clear;
  637.     ScanForFiles(Startup);
  638.     ScanForFiles(CommonStartup);
  639.     ScanForFiles(AltStartup);
  640. end;
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650. end.
  651.