从Delphi exe执行RegEdit

use*_*284 -1 delphi

我正在使用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;
Run Code Online (Sandbox Code Playgroud)

但它没有编译.我的要求是将子节点01的可扩展字符串值写为"%SystemRoot%\ System32\Application Wizard 01.dll".我的项目的Active Platform是32Bit,但也添加了64Bit,我的应用程序将在管理员的平台下运行.

我认为我的问题可以通过调用Wow64DisableWow64FsRedirection函数Wow64EnableWow64FsRedirection函数来解决.但目前尚不清楚何时调用它.这是我项目的另一个细节.

Sir*_*ufo 5

不要试图失败重定向,只需使用此力量让您的生活更轻松.

如果将DLL文件放入全局Windows存储区,则必须将其放入该System32文件夹中.但是,此文件夹根据操作系统平台和应用程序支持的平台而有所不同.

x32 OS / x32 app -> %SystemRoot%\System32
x64 OS / x64 app -> %SystemRoot%\System32
x64 OS / x32 app -> %SystemRoot%\SysWow64
Run Code Online (Sandbox Code Playgroud)

为方便起见,Windows 在x64操作系统上从x32应用程序写入注册表时也具有自动重定向功能,因此您无需为此进行额外处理.

按照设计,您使用此代码编写始终是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;
Run Code Online (Sandbox Code Playgroud)

所有三种情况的一个代码库,没有任何编译器开关或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
Run Code Online (Sandbox Code Playgroud)

这是示例应用程序(两个平台的一个代码库).有一个编译器开关,用于设置表单标题.就这样.

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.
Run Code Online (Sandbox Code Playgroud)