tags:

views:

129

answers:

2

hi all i am trying to store some settings in resource of my application but failed i dont want to use ini file or registry methods i am using this code

    var
    data :string;

  procedure WriteSettings(ServerFile: string; Settings: string);
    var
     ResourceHandle: THandle;
     pwServerFile: PWideChar;
    begin
     GetMem(pwServerFile, (Length(ServerFile) + 1) * 2);
     try
       StringToWideChar(ServerFile, pwServerFile, Length(ServerFile) * 2);
       ResourceHandle := BeginUpdateResourceW(pwServerFile, False);
       UpdateResourceW(ResourceHandle, MakeIntResourceW(10), 'SETTINGS', 0, @Settings[1], Length(Settings) + 1);
       EndUpdateResourceW(ResourceHandle, False);
     finally
       FreeMem(pwServerFile);
     end;
    end;
    function ReadSettings(ServerFile: string): string;
    var
      ServerModule: HMODULE;
      ResourceLocation: HRSRC;
      ResourceSize: dword;
      ResourceHandle: THandle;
      ResourcePointer: pointer;
    begin
      ServerModule := LoadLibrary(pchar(ServerFile));
      try
        ResourceLocation := FindResource(ServerModule, 'SETTINGS', RT_RCDATA);
        ResourceSize := SizeofResource(ServerModule, ResourceLocation);
        ResourceHandle := LoadResource(ServerModule, ResourceLocation);
        ResourcePointer := LockResource(ResourceHandle);
        if ResourcePointer <> nil then
        begin
          SetLength(Result, ResourceSize - 1);
          CopyMemory(@Result[1], ResourcePointer, ResourceSize);
          FreeResource(ResourceHandle);
        end;
      finally
        FreeLibrary(ServerModule);
      end;
    end;
  procedure TForm1.saveClick(Sender: TObject);
begin
    writesettings(paramastr(0),'true');  
end;
 procedure TForm1.ReadClick(Sender: TObject);
begin
   data:=readsettings(paramstr(0));  
end;

 begin
   if data='true' then checkbox1.checked:=true;
 end

but is nit storing the that i wrote to resource :( is there any other better options? any help please

+4  A: 

Having your program modify itself is a bad idea. As a couple people already pointed out, this will fail badly under Vista and Win7 in most cases. It's better not to fight the operating system. Windows already provides a couple different ways for your program to store its settings. You can drop an INI or other config file in some folder outside of Program Files, or you can store it in the Registry, which is probably the best option.

Mason Wheeler
By "some folder outside of Program Files", Mason Wheeler means "C:\Users\<User Name>\AppData\Local\<Your Company>\<Your Product>\<Product Version>", the first part of which (up to and including "Local") should be obtained dynamically by means of the `SHGetFolderPath` function of the Windows API (http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx).
Andreas Rejbrand
Yes, basically. If you're on Vista or later, that's the right path too. Otherwise SHGetFolderPath will send you somewhere else. (Which is why it should be used instead of trying to hardcode the path.)
Mason Wheeler
"Having your program modify itself is a bad idea". Agreed. Furthermore, it's highly suspicious behavior and would probably be flagged as malware. Makes me wonder if DEP or similar may be preventing his code from working in the first place? Admittedly, I jumped into "bad idea" lecturing, without looking at the code much.
Chris Thornton
+6  A: 

The documentation for BeginUpdateResource clearly states why your code doesn't work (emphasis added):

pFileName [in]

LPCTSTR

The binary file in which to update resources. An application must be able to obtain write-access to this file; the file referenced by pFileName cannot be currently executing. If pFileName does not specify a full path, the system searches for the file in the current directory.

You might have been able to deduce the cause of the error yourself if you were checking the API function's return value and calling GetLastError on failure, like the documentation advises.

You can store settings in a resource, but you can't store settings in a resource of the program whose settings you're trying to store. And now that we've established that you're not allowed to store settings in the program itself, you may as well just abandon the resource idea and use a more conventional method of storing settings in an external location, such as the registry, an INI file, or whatever. You might still wish to read a set of default settings from a resource if you find that the external location doesn't yet have any settings, as might happen after a fresh install.

Rob Kennedy