2010-07-16 51 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