2010-07-16 80 views
1

我试图存储在我的应用程序 的资源的一些设置设置,但未能 我不想使用INI文件或注册表方法 我使用这个代码如何存储资源

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 

但nit存储我写的资源:( 有没有其他更好的选择吗? 请任何帮助

+0

'if data:='true'then checkbox1.checked:= true;'?也许你的意思是'如果data ='true',那么checkbox1.checked:= true;'? – 2010-07-16 16:44:40

+0

对错误的错误 – steve0 2010-07-16 17:08:47

+6

请注意,具有普通用户权限的用户将无法在程序文件文件夹中写入文件。所以这对他们不起作用。而从Vista开始,UAC甚至不会为管理员工作,除非他们使用提升的权限运行您的程序。 – 2010-07-16 17:13:37

回答

7

The documentation for BeginUpdateResource明确指出为什么你的代码不起作用:

pFileName [中]

LPCTSTR

二进制文件中更新资源。应用程序必须能够获得该文件的写入权限; 由pFileName引用的文件目前无法执行。如果pFileName未指定完整路径,系统将在当前目录中搜索文件。

如果您正在检查API函数的返回值并在失败时调用GetLastError(如文档建议),您可能自己可以自己推断出错的原因。

您可以将设置存储在资源中,但不能将设置存储在您尝试存储其设置的程序资源中。现在,我们已经确定您不允许在程序中存储设置,您最好放弃资源创意并使用更常规的方法将设置存储在外部位置,例如注册表, INI文件,或其他。如果您发现外部位置还没有任何设置,您可能仍希望从资源中读取默认设置设置,如全新安装后可能发生的那样。

5

让你的程序修改自己是一个坏主意。作为一对夫妇已经指出,这将在Vista下严重失败和Win7在米最后的情况。最好不要打击操作系统。 Windows已经为您的程序提供了几种不同的方式来存储其设置。您可以在程序文件之外的某个文件夹中放置INI或其他配置文件,也可以将其存储在注册表中,这可能是最佳选择。 (强调)

+2

由“some文件夹以外的程序文件“,Mason Wheeler的意思是”C:\ Users \ \ AppData \ Local \ <您的公司> \ <您的产品> \ <产品版本>“,其中的第一部分“)应该通过Windows API的SHGetFolderPath函数动态获取(http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx)。 – 2010-07-16 17:53:17

+1

是的,基本上。如果你使用Vista或更高版本,那也是正确的道路。否则SHGetFolderPath会将你发送到别的地方。 (这就是为什么它应该被用来代替尝试硬编码路径。) – 2010-07-16 18:15:02

+2

“让你的程序修改自己是一个坏主意”。同意。此外,这是高度可疑的行为,可能会被标记为恶意软件。让我怀疑DEP或类似的东西是否会阻止他的代码在第一位工作?无可否认,我跳入“糟糕的主意”讲座,没有看太多的代码。 – 2010-07-16 18:20:31