我正在Delphi XE2 Project在Windows注册表中编写一些值。我想在Delphi环境中运行RegEdit。我尝试过以下代码:
procedure TMainForm.BitBtn01Click(Sender: TObject);
begin
ShellExecute(handle,'','C:\WINDOWS\regedit.exe',
'[HKEY_CLASSES_ROOT\CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 01]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,\
00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\
41,00,70,00,70,00,6c,00,69,00,63,00,61,00,74,00,69,00,6f,00,6e,00,20,00,57,\
00,69,00,7a,00,61,00,72,00,64,00,20,00,30,00,31,00,2e,00,64,00,6c,00,6c,00,\
00,00'
,nil,SW_SHOW);
end;
但它没有编译。我的要求是将子节点01的可扩展字符串值写为“%SystemRoot%\ System32 \ Application Wizard 01.dll”。我的项目的Active Platform是32Bit,但也添加了64Bit,我的应用程序将在管理员的平台下运行。
我认为我的问题可以通过致电Wow64DisableWow64FsRedirection Function和Wow64EnableWow64FsRedirection Function来解决。但目前尚不清楚何时调用它。 以下是my project的另一个细节。
答案 0 :(得分:5)
不要试图使重定向失败,只需使用此力量就可以让您的生活更轻松。
如果将DLL文件放入全局Windows应用商店,则必须将其放入System32
文件夹。但是,此文件夹根据操作系统平台和应用程序支持的平台而有所不同。
x32 OS / x32 app -> %SystemRoot%\System32
x64 OS / x64 app -> %SystemRoot%\System32
x64 OS / x32 app -> %SystemRoot%\SysWow64
为了您的方便,在 x64操作系统上从 x32应用写入注册表时,Windows也具有自动重定向功能,因此您无需进行额外处理对此。
按照设计,您使用此代码编写始终是DLL文件的正确路径。
const
c_RegKey = 'CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 01';
c_DllFile = '%systemroot%\system32\Understanding3264_lib.dll';
var
LReg : TRegistry;
begin
LReg := TRegistry.Create;
try
LReg.RootKey := HKEY_CLASSES_ROOT;
if LReg.OpenKey( c_RegKey, True )
then
try
// we write as REG_EXPAND_SZ to flag that this contain environment variables
// that has to be expanded
LReg.WriteExpandString( '', c_DllFile );
finally
LReg.CloseKey;
end
else
raise Exception.CreateFmt( 'Not allowed to create the registry key HKCR\%s', [c_DllFile] );
finally
LReg.Free;
end;
end;
所有三种情况的一个代码库,没有任何编译器开关或OS平台检查。
但是你必须注意安装,把文件放在正确的位置。
以下是Inno Setup的一个示例脚本,它处理两个平台。在x32操作系统上它只会安装x32应用程序,在x64操作系统上它将安装两个(x32 / x64)应用程序。
; Extended sample from
; -- 64BitTwoArch.iss --
; Demonstrates how to install a program built for two different
; architectures (x86 and x64) using a single installer.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING .ISS SCRIPT FILES!
[Setup]
AppName=Understanding3264
AppVersion=1.0
AppId={{BD2CF2C0-B8A4-40C9-8161-917544CB2E5C}
DefaultDirName={pf}\Understanding3264
DefaultGroupName=Understanding3264
UninstallDisplayIcon={app}\Understanding3264.exe
Compression=lzma2
SolidCompression=yes
OutputDir=Setup
OutputBaseFilename=Understanding3264_Setup
; "ArchitecturesInstallIn64BitMode=x64" requests that the install be
; done in "64-bit mode" on x64, meaning it should use the native
; 64-bit Program Files directory and the 64-bit view of the registry.
; On all other architectures it will install in "32-bit mode".
ArchitecturesInstallIn64BitMode=x64
; Note: We don't set ProcessorsAllowed because we want this
; installation to run on all architectures (including Itanium,
; since it's capable of running 32-bit code too).
[Files]
; 32bit Platform only 32bit Application
Source: ".\Win32\Release\Understanding3264.exe"; DestDir: "{app}"; Check: not Is64BitInstallMode
Source: ".\Win32\Release\Understanding3264_lib.dll"; DestDir: "{sys}"; Check: not Is64BitInstallMode
; 64bit Platforms install 64bit and 32bit Application
Source: ".\Win64\Release\Understanding3264.exe"; DestDir: "{app}"; Check: Is64BitInstallMode
Source: ".\Win64\Release\Understanding3264_lib.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode
Source: ".\Win32\Release\Understanding3264.exe"; DestDir: "{app}\x32"; Check: Is64BitInstallMode
Source: ".\Win32\Release\Understanding3264_lib.dll"; DestDir: "{syswow64}"; Check: Is64BitInstallMode
[Icons]
Name: "{group}\Understanding3264"; Filename: "{app}\Understanding3264.exe"
; link to x32 app when on x64 OS
Name: "{group}\Understanding3264 (32bit)"; Filename: "{app}\x32\Understanding3264.exe"; Check: Is64BitInstallMode
Name: "{group}\{cm:UninstallProgram, Understanding3264}"; Filename: "{uninstallexe}"
[Registry]
; clean the registry on uninstall
Root: "HKCR"; Subkey: "CLSID\{{00000000-0000-0000-0000-000000000001}"; Flags: dontcreatekey uninsdeletekey
; if x64 OS we also have to take care on the registry key created by the x32 application
Root: "HKCR32"; Subkey: "CLSID\{{00000000-0000-0000-0000-000000000001}"; Flags: dontcreatekey uninsdeletekey; Check: Is64BitInstallMode
这是示例应用程序(两个平台的一个代码库)。有一个编译器开关,用于设置表单标题。就是这样。
unit Main_ViewU;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
const
c_RegKey = 'CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 01';
// Because Windows does a magic redirection, we can use the same string
// for both platforms x32/x64
// x32 app on x32 OS -> %systemroot%\system32\Understanding3264_lib.dll
// x64 app on x64 OS -> %systemroot%\system32\Understanding3264_lib.dll
// x32 app on x64 OS -> %systemroot%\SysWow64\Understanding3264_lib.dll
c_DllFile = '%systemroot%\system32\Understanding3264_lib.dll';
type
TGetInfoFunc = function : WideString; stdcall;
type
TMain_View = class( TForm )
GetInfo_Button : TButton;
RegisterLib_Button : TButton;
DllFileName_Label : TLabel;
procedure FormCreate( Sender : TObject );
procedure GetInfo_ButtonClick( Sender : TObject );
procedure RegisterLib_ButtonClick( Sender : TObject );
private
public
end;
var
Main_View : TMain_View;
implementation
{$R *.dfm}
uses
Registry;
function ExpandEnvironmentStringsStr( const AStr : string ) : string;
begin
SetLength( Result, ExpandEnvironmentStrings( PChar( AStr ), nil, 0 ) );
ExpandEnvironmentStrings( PChar( AStr ), PChar( Result ), Length( Result ) );
end;
procedure TMain_View.GetInfo_ButtonClick( Sender : TObject );
var
LReg : TRegistry;
LRegDataInfo : TRegDataInfo;
LDllFileName : string;
LLib : HMODULE;
LFunc : TGetInfoFunc;
LStr : string;
begin
LReg := TRegistry.Create;
try
LReg.RootKey := HKEY_CLASSES_ROOT;
if LReg.OpenKeyReadOnly( c_RegKey )
then
if LReg.GetDataInfo( '', LRegDataInfo )
then
begin
case LRegDataInfo.RegData of
rdString : // just read the string
LDllFileName := LReg.ReadString( '' );
rdExpandString : // string needs to be expanded
LDllFileName := ExpandEnvironmentStringsStr( LReg.ReadString( '' ) );
end;
end;
finally
LReg.Free;
end;
// just for information
DllFileName_Label.Caption := LDllFileName;
// no info from registry
if LDllFileName = ''
then
raise Exception.Create( 'Not registered' );
// load the library
LLib := LoadLibrary( PChar( LDllFileName ) );
if LLib <> 0
then
try
@LFunc := GetProcAddress( LLib, 'GetInfo' );
LStr := LFunc;
finally
FreeLibrary( LLib );
end
else
raise Exception.CreateFmt( 'Dll-File "%s" not found!', [LDllFileName] );
// show the information
ShowMessage( LStr );
end;
procedure TMain_View.RegisterLib_ButtonClick( Sender : TObject );
var
LReg : TRegistry;
begin
LReg := TRegistry.Create;
try
LReg.RootKey := HKEY_CLASSES_ROOT;
if LReg.OpenKey( c_RegKey, True )
then
try
// we write as REG_EXPAND_SZ to flag that this contain environment variables
// that has to be expanded
LReg.WriteExpandString( '', c_DllFile );
finally
LReg.CloseKey;
end
else
raise Exception.CreateFmt( 'Not allowed to create the registry key HKCR\%s', [c_DllFile] );
finally
LReg.Free;
end;
end;
procedure TMain_View.FormCreate( Sender : TObject );
begin
Caption := Application.Title{$IFDEF Win64} + ' (x64)'{$ELSE} + ' (x32)'{$ENDIF};
end;
end.
答案 1 :(得分:4)
尝试这样:
Uses
ShellApi;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(handle,'','C:\WINDOWS\regedit.exe',
'[HKEY_CLASSES_ROOT\CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 01]'+
'@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,'+
'00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,'+
'41,00,70,00,70,00,6c,00,69,00,63,00,61,00,74,00,69,00,6f,00,6e,00,20,00,57,'+
'00,69,00,7a,00,61,00,72,00,64,00,20,00,30,00,31,00,2e,00,64,00,6c,00,6c,00,'+
'00,00', nil, SW_SHOW);
end;
答案 2 :(得分:3)
您不使用有效的字符串。在字符串中执行换行符时,需要将其关闭并用+符号连接。
e.g:
AFunction(...,
'text1' +
'text2' +
'text3', ...);
或将整个字符串参数写在一行中。