从Delphi exe执行RegEdit [英] Executing RegEdit from Delphi exe

查看:128
本文介绍了从Delphi exe执行RegEdit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Delphi XE2 Project 在Windows注册表中编写一些值。我正在Delphi环境中运行RegEdit。我尝试了以下代码:

I am having Delphi XE2 Project to write some values in Windows Registry. I am trying to run RegEdit in Delphi Environment. I have tried the following codes :

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;

但它不是编译。我的要求是将Subnode 01的Expandable String值写为%SystemRoot%\System32\Application Wizard 01.dll。我的项目的活动平台是32位,但64位也被添加,我的应用程序将以两个平台作为管理员运行。

But it is not compiling. My requirement is to write Expandable String Value for Subnode 01 as "%SystemRoot%\System32\Application Wizard 01.dll". Active Platform for my project is 32Bit but 64Bit is also added and my application will run under both the platform as Administrator.

我认为我的问题可以通过调用 Wow64DisableWow64FsRedirection功能 Wow64EnableWow64FsRedirection功能 。但是不清楚何时调用它。
这是我的项目的另一个细节。

I think my problem can be resolved by calling Wow64DisableWow64FsRedirection Function and Wow64EnableWow64FsRedirection Function. But it is not clear when to call it. Here is another details of my project.

推荐答案

不要试图失败重定向,只需使用这个力量让你的生活更轻松。

Don't try to fail the redirection, just use this force to make your life easier.

如果你把一个DLL文件到全局的Windows商店,你必须把它放到 System32 文件夹中。但是这个文件夹根据操作系统平台和应用程序支持的平台而有所不同。

If you put a DLL file to the global Windows store, you have to put it into the System32 folder. But this folder differs depending on the OS platform and the platform supported by your application.

x32 OS / x32 app -> %SystemRoot%\System32
x64 OS / x64 app -> %SystemRoot%\System32
x64 OS / x32 app -> %SystemRoot%\SysWow64

为方便起见,Windows也有自动重定向,当写入注册表时 x64应用 x64操作系统,所以您不必再为此处理额外的操作。

For your convenience Windows has an automated redirection also when writing to the registry from a x32 app on a x64 OS so you don't have to put an extra handling for this.

根据设计,您使用此代码始终是DLL文件的正确路径。

As designed you write with this code always the right path to your DLL file.

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;

所有三种情况的一个代码库,无需任何编译器开关或操作系统平台检查。

One codebase for all three cases without any compiler switches or OS platform checking.

但是,您必须注意安装,将文件放在正确的位置。

But you have to take care on installation, to put the files in the right place.

这是一个用于Inno Setup的示例脚本它们处理两个平台。在x32操作系统上,它只会安装x32应用程序,在x64操作系统上,它将安装(x32 / x64)应用程序。

Here is an example script for Inno Setup which handles both platforms. On x32 OS it will only install the x32 app, on x64 OS it will install both (x32/x64) apps.

; 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

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

and this is the sample application (one codebase for both platforms). There is one compiler switch, to set the form caption. That's all.

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.

这篇关于从Delphi exe执行RegEdit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆