2010-12-19 70 views
4

使用delphi创建32位应用程序根据应用程序是运行在win32还是win64 windows计算机上,我无法访问所有配置单元。这里是一个链接,缺省访问:http://msdn.microsoft.com/en-us/library/aa390789(v=VS.85).aspx访问注册表中的所有3个配置单元

我只是想创建一个应用程序,而不是一个单独的版本为32 & 64.我想从32位注册表配置单元使用WMI和检索信息时, 64位注册表配置单元和WOW6432Node。有FLAGS设置,但我不知道如何发送标志与我的delphi应用程序的常规WMI查询调用。以下是有关国旗的信息:http://msdn.microsoft.com/en-us/library/aa393067(v=VS.85).aspx

GLibWmi & DelphiWmiCodeCreator exmple:

function GetWMIObject(const objectName: String): IDispatch; //create the Wmi instance 
var 
    chEaten: Integer; 
    BindCtx: IBindCtx; 
    Moniker: IMoniker; 
begin 
    OleCheck(CreateBindCtx(0, bindCtx)); 
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker)); 
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result)); 
end; 

procedure GetWin32_StartupCommandInfo; 
var 
    objWMIService : OLEVariant; 
    colItems  : OLEVariant; 
    colItem  : OLEVariant; 
    oEnum   : IEnumvariant; 
    iValue  : LongWord; 
begin; 
    objWMIService := GetWMIObject('winmgmts:\\localhost\root\CIMV2'); 
    colItems  := objWMIService.ExecQuery('SELECT * FROM Win32_StartupCommand','WQL',0); 
    oEnum   := IUnknown(colItems._NewEnum) as IEnumVariant; 
    while oEnum.Next(1, colItem, iValue) = 0 do 
    begin 
    Writeln(''); 
    end; 
end; 

修改后的代码:

procedure GetWin32_StartupCommandInfo(aIDispatch: IDispatch); 
var 
    objWMIService : OLEVariant; 
    colItems  : OLEVariant; 
    colItem  : OLEVariant; 
    oEnum   : IEnumvariant; 
    iValue  : LongWord; 
begin; 
    objWMIService := aIDispatch; //GetWMIObject('winmgmts:\\localhost\root\CIMV2'); 
    colItems  := objWMIService.ExecQuery('SELECT * FROM Win32_StartupCommand','WQL',0); 
    oEnum   := IUnknown(colItems._NewEnum) as IEnumVariant; 
    while oEnum.Next(1, colItem, iValue) = 0 do 
    begin 
    with Form1.lst1 do begin 

     items.Add(Format('Caption="%s"; Location="%s"',[colItem.Caption,colItem.Location]));// String 
     {items.Add(Format('Command   %s',[colItem.Command]));// String 
     items.Add(Format('Description  %s',[colItem.Description]));// String 
     items.Add(Format('Location  %s',[colItem.Location]));// String 
     items.Add(Format('Name   %s',[colItem.Name]));// String 
     items.Add(Format('SettingID  %s',[colItem.SettingID]));// String 
     items.Add(Format('User   %s',[colItem.User]));// String 
     items.Add(Format('UserSID   %s',[colItem.UserSID]));// String 
     } 
     items.Add(''); 

    end; 
    end; 
end; 

function MyConnectWMI(wmiHost:string; var Services: ISWbemServices):Boolean; 
const 
    STR_CIM2_ROOT ='root\CIMV2'; 
    STR_EMPTY = ''; 
var 
    NVS: SWbemNamedValueSet; 
    providerArchitecture : OleVariant; 
    requiredArchitecture : OleVariant; 
    Locator : ISWbemLocator; //CoSWbemLocator; 
begin 
    try 
    providerArchitecture := 32; // or 64 
    requiredArchitecture := true; 

    NVS := CoSWbemNamedValueSet.Create(); 
    NVS.Add('__ProviderArchitecture', providerArchitecture , 0); 
    NVS.Add('__RequiredArchitecture', requiredArchitecture , 0); 
    // Create the Location object 
    Locator := CoSWbemLocator.Create(); 
    // Connect to the WMI service, with the root\cimv2 namespace 
    Services := Locator.ConnectServer(wmiHost, 
     STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY, 
     STR_EMPTY,STR_EMPTY, 0, NVS); 

    Result := True; 
    except 
    Result := False; 
    end; 
end; 

procedure TForm1.btn1Click(Sender: TObject); 
var 
    aServices: ISWbemServices; 
begin 
    if MyConnectWMI('localhost', aServices) then 
    GetWin32_StartupCommandInfo(aServices); 
end; 

回答

2

您正在使用的WMI别名而据我可以看到你不能通过它指定你需要的选项。您需要使用SWbemLocator对象,让我们传递SWbemNamedValueSet作为最终参数。

GLibWMI的UProcedures.pas文件中有一个ConnectWMI函数。它通过一个零到最终的parm:

Services := Locator.ConnectServer(wmiHost, 
     STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY, 
     STR_EMPTY,STR_EMPTY, 0, nil); 

您需要创建一种替代,是这样的:

var 
    NVS: SWbemNamedValueSet; 
    providerArchitecture : OleVariant; 
    requiredArchitecture : OleVariant; 
///// 

    providerArchitecture := 32; // or 64 
    requiredArchitecture := true; 

    NVS := CoSWbemNamedValueSet.Create(); 
    NVS.Add('__ProviderArchitecture', providerArchitecture , 0); 
    NVS.Add('__RequiredArchitecture', requiredArchitecture , 0); 

    // Create the Location object 
    Locator := CoSWbemLocator.Create(); 
    // Connect to the WMI service, with the root\cimv2 namespace 
    Services := Locator.ConnectServer(wmiHost, 
     STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY, 
     STR_EMPTY,STR_EMPTY, 0, NVS); 

,将让你的ISWbemServices接口上,然后可以执行使用ExecQuery。

通过的StdRegProv访问注册表 -


procedure Get_RegistryValue(aIDispatch: IDispatch); 
var 
    objWMIService : OLEVariant; 

    strKeyPath : OLEVariant; 
    strValue : OLEVariant; 
    strOut : OLEVariant; 

    objStdRegProv : OLEVariant; 
begin; 
    objWMIService := aIDispatch; 

    objStdRegProv := objWMIService.Get('StdRegProv'); 

    strKeyPath := 'Software\Microsoft\Wbem\CIMOM'; 
    strValue := 'Logging'; 

    objStdRegProv.GetStringValue(HKEY_LOCAL_MACHINE, strKeyPath, strValue, strOut); 

    with Form1.lst1 do begin 
     items.Add(strOut); 
    end; 
    end; 
end; 


// connect to root\default instead of cimv2 
function MyConnectWMI(wmiHost:string; var Services: ISWbemServices):Boolean; 
const 
    STR_DEFAULT_ROOT = 'root\default' 
    STR_EMPTY = ''; 
var 
    NVS: SWbemNamedValueSet; 
    providerArchitecture : OleVariant; 
    requiredArchitecture : OleVariant; 
    Locator : ISWbemLocator; //CoSWbemLocator; 
begin 
    try 
    providerArchitecture := 32; // or 64 
    requiredArchitecture := true; 

    NVS := CoSWbemNamedValueSet.Create(); 
    NVS.Add('__ProviderArchitecture', providerArchitecture , 0); 
    NVS.Add('__RequiredArchitecture', requiredArchitecture , 0); 
    // Create the Location object 
    Locator := CoSWbemLocator.Create(); 
    // Connect to the WMI service, with the root\cimv2 namespace 
    Services := Locator.ConnectServer(wmiHost, 
     STR_DEFAULT_ROOT, {user}STR_EMPTY, {password}STR_EMPTY, 
     STR_EMPTY,STR_EMPTY, 0, NVS); 

    Result := True; 
    except 
    Result := False; 
    end; 
end; 
+0

我得到它的工作,但只有当providerArchitecture设置为64,如果我有它设置为32,我收到了EOleException错误:“提供程序加载失败” 。我使用Delphi 2010运行Win7 64Bit。 – Logman 2011-01-11 15:35:46

+0

CHeck上面在我的原始文章在修订部分。代码BREAK在执行“ExecQuery”时执行,而不是在创建连接时执行。 – Logman 2011-01-11 15:44:47

+0

这将归结为供应商。 Win32_StartupCommand由Win32提供者提供,而不是注册表提供者。此页http://msdn.microsoft.com/en-us/library/aa394570%28v=VS.85%29.aspx列出提供程序。注册表提供商在64位平台上提到了两个版本。 – vickd 2011-01-11 23:18:28