Announcement

Collapse
No announcement yet.

Fehler beim Speichern in Reg_Multi_SZ

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Fehler beim Speichern in Reg_Multi_SZ

    Hi, also ich habe folgendes Problem.
    Ich lasse eine De-Installation durchführen.
    Dabei kann der Anwender entscheiden ob er seine angelegte Instanz des MS SQL Server löschen möchte.
    Alles funktioniert wunderbar, nur diese eine Schritt nicht.
    Ich lese die eingetragenen Werte unter "Software\Microsoft\Microsoft SQL Server" - "InstalledInstances" aus.
    Dann kontrolliere ich welche Instanz die von dem Anwender verwendete Instanz ist und lasse diese aussen vor.
    Dann will ich die Werte wieder abspeichern, und da passiert es...

    Hier mal mein bisheriger Lösungsansatz:

    Code:
            aRegKey := TRegistry.Create;
    
              try
    
                 with aRegKey
                 do begin
    
                  RootKey := HKEY_LOCAL_MACHINE;
    
                  OpenKey(cSQL, False);
    
                  iSize := aRegKey.GetDataSize('InstalledInstances');
    
                    if (iSize > 0)
                    then begin
    
                     SetLength(sTemp, iSize);
    
                     aRegKey.ReadBinaryData('InstalledInstances', sTemp[1], iSize);
    
                     bExit := False;
    
                       repeat
    
                        iPos := Pos(#0, sTemp);
    
                          if iPos <> 0
                          then
    
                             if sTemp[iPos + 1] <> #0
                             then
    
                              sTemp[iPos] := #13
    
                             else
    
                              bExit := True;
    
                       until bExit;
    
                     SQLInstanz.Text := sTemp;
    
                    end;
    
                 end;
    
              finally
    
               aRegKey.Free;
    
              end;
    
           NeuInstanz := TStringList.Create;
    
              for Filter := 0 to SQLInstanz.Count - 1
              do begin
    
                 if SQLInstanz[Filter] <> InstanzName
                 then begin
    
                  NeuInstanz.Add(SQLInstanz[Filter]);
    
                 end;
    
              end;
    
            dwDataSize := Length(NeuInstanz.Text);
    
            RegCreateKeyEx(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Microsoft SQL Server', 0, '', REG_OPTION_NON_VOLATILE, KEY_WRITE, nil, aHandle, @dwDisposition);
    
            RegSetValueEx(aHandle, 'InstalledInstances', 0, REG_MULTI_SZ, PString(NeuInstanz.Text), dwDataSize);
    Ich bekomme dann z.B. so etwas raus: MSSQLServer□□

    Ich hoffe ich konnte euch mein Problem erläutern.

    mfg Cre@or
    Zuletzt editiert von Cre@or; 28.08.2008, 12:05.

  • #2
    Hier mal der Link von dem Quelltext den ich als Vorlage genommen habe: Click

    Comment


    • #3
      Neuer Denkansatz vielleicht zu diesem Thema im allgemeinen. Da ich ja die Instanz löschen möchte, gibt es denn vielleicht eine Möglichkeit die Instanz vom Microsoft SQL Server, diesen selber löschen zu lassen?
      Wenn ja, was müsste ich tun?

      mfg Cre@or

      Comment


      • #4
        SQL Server 2000 oder 2005?

        Comment


        • #5
          Danke erst mal für die Nachfrage!
          SQL Server 2000.
          Aber im Grunde soll diese De-Installation mit jedem gehen, zumindest hoffe ich das.
          Ich habe allerdings bereits einen anderen Lösungsweg eingeschlagen.
          Hab diesen Code gerade erstellt. Mal schauen ob das so läuft wie ich mir das vorstelle...
          (ist noch nicht ganz fertig?)

          Code:
           function DelDir(dir: string): Boolean;
          
            var
          
             fos: TSHFileOpStruct;
          
           begin
          
            ZeroMemory(@fos, SizeOf(fos));
          
              with fos
              do begin
          
               wFunc  := FO_DELETE;
               fFlags := FOF_SILENT or FOF_NOCONFIRMATION;
               pFrom  := PChar(dir + #0);
          
              end;
          
            Result := (0 = ShFileOperation(fos));
          
           end;
          
           procedure TForm1.JaClick(Sender: TObject);
          
            var
          
             Reg         : TRegistry;
          
             InstanzPfad : String;
             InstanzName : String;
             MSIExec     : String;
          
             Batch       : TStringList;
          
           begin
          
            Reg := TRegistry.Create;
          
              try
          
               Reg.RootKey := HKEY_LOCAL_MACHINE;
          
               Reg.OpenKey(cInstanz, false);
          
               InstanzPfad := Reg.ReadString('InstanzPfad');
          
               InstanzName := Reg.ReadString('Instanz');
          
              finally
          
               Reg.Free;
          
              end;
          
            Reg := TRegistry.Create;
          
              try
          
               Reg.RootKey := HKEY_LOCAL_MACHINE;
          
               Reg.OpenKey(cSQL + '\' + InstanzName + '\Setup', false);
          
               MSIExec := Reg.ReadString('ProductCode');
          
               Reg.DeleteKey(cSQL + '\' + InstanzName);
          
              finally
          
               Reg.Free;
          
              end;
          
            Reg := TRegistry.Create;
          
              try
          
               Reg.RootKey := HKEY_LOCAL_MACHINE;
          
               Reg.OpenKey(cUninstall + '\' + MSIExec, false);
          
               MSIExec := Reg.ReadString('ModifyPath');
          
              finally
          
               Reg.Free;
          
              end;
          
              if DirectoryExists(InstanzPfad) = True
              then begin
          
               Batch := TStringList.Create;
          
               Batch.Add(MSIExec);
          
               Batch.Add('net stop MSSQL$' + InstanzName);
          
               Batch.Add('rmdir /s /q ' + InstanzPfad);
          
               Batch.SaveToFile('C:\Delete.bat');
          
               ShellExecute(0, nil, 'C:\Delete.bat', nil, nil, SW_NORMAL);
          
               Sleep(10000);
          
               DelDir(InstanzPfad);
          
               DeleteFile('C:\Delete.bat');
          
               Application.Terminate;
          
              end;
          
           end;
          Zuletzt editiert von Cre@or; 29.08.2008, 13:57.

          Comment


          • #6
            So, jetzt funzt es...

            Code:
             procedure TForm1.JaClick(Sender: TObject);
            
              var
            
              // Variablen die für das Auslesen der Reg_Multi_SZ Werte verantwortlich sind.
            
               Reg           : TRegistry;
            
               InstanzName   : String;
               InstanzPfad   : String;
               MSIExec       : String;
            
               Batch         : TStringList;
            
             begin
            
              Reg := TRegistry.Create;
            
                try
            
                 Reg.RootKey := HKEY_LOCAL_MACHINE;
            
                 Reg.OpenKey(cInstanz, false);
            
                 InstanzPfad := Reg.ReadString('InstanzPfad');
            
                 InstanzName := Reg.ReadString('Instanz');
            
                finally
            
                 Reg.Free;
            
                end;
            
              Reg := TRegistry.Create;
            
                try
            
                 Reg.RootKey := HKEY_LOCAL_MACHINE;
            
                 Reg.OpenKey(cSQL + '\' + InstanzName + '\Setup', false);
            
                 MSIExec := Reg.ReadString('ProductCode');
            
                 Reg.DeleteKey(cSQL + '\' + InstanzName);
            
                finally
            
                 Reg.Free;
            
                end;
            
              Reg := TRegistry.Create;
            
                try
            
                 Reg.RootKey := HKEY_LOCAL_MACHINE;
            
                 Reg.OpenKey(cUninstall + '\' + MSIExec, false);
            
                 MSIExec := Reg.ReadString('UninstallString');
            
                finally
            
                 Reg.Free;
            
                end;
            
                if DirectoryExists(InstanzPfad) = True
                then begin
            
                 Batch := TStringList.Create;
            
                 Batch.Add(MSIExec);
            
                 Batch.Add('rmdir /s /q "' + InstanzPfad + '"');
            
                 Batch.SaveToFile('C:\Delete.bat');
            
                 Application.Terminate;
            
                end;
            
             end;
            Die Batchdatei lasse ich später durch Inno-Setup beseitigen.
            Zuletzt editiert von Cre@or; 08.09.2008, 11:51. Reason: Code Änderung, winzig kleinen Bug entfernt...

            Comment


            • #7
              Hier mal noch die Registry-Pfade...

              Code:
               resourcestring
              
                cInstanz    = 'Zur Installation gewaehlter Pfad\...';
              
                cSQL = 'Software\Microsoft\Microsoft SQL Server';
              
                cUninstall = 'Software\Microsoft\Windows\CurrentVersion\Uninstall';

              Comment

              Working...
              X