[INI]
Filename: "{app}\config\my.ini"; Section: "ADDRESS"; Key: "LOCALIP"; String: "{{ConfigPage1.Values[1]}}" ;Check:IsSystemIPEquallocalIP;
[code]
function IsSystemIPEquallocalIP():Boolean;
begin
if ConfigPage1.Values[1] = ConfigPage1.Values[2] then
Result := False
else
Result :=True;
简单说明下:这个是inno setup脚本我想实现在运行的时候,把我本机的ip地址写到“string”中,条件是systemip和localip相等时,才写入到my.ini的LOCALIP字段中,如何实现?(上面的代码是我的代码,不正确)
还有就是如何获得安装第一步的选择语言页的ID号?
Filename: "{app}\config\my.ini"; Section: "ADDRESS"; Key: "LOCALIP"; String: "{{ConfigPage1.Values[1]}}" ;Check:IsSystemIPEquallocalIP;
[code]
function IsSystemIPEquallocalIP():Boolean;
begin
if ConfigPage1.Values[1] = ConfigPage1.Values[2] then
Result := False
else
Result :=True;
简单说明下:这个是inno setup脚本我想实现在运行的时候,把我本机的ip地址写到“string”中,条件是systemip和localip相等时,才写入到my.ini的LOCALIP字段中,如何实现?(上面的代码是我的代码,不正确)
还有就是如何获得安装第一步的选择语言页的ID号?
解决方案 »
- ApiHook 的问题
- 我有一套idtcpserver+idtcpclient方式的客户端跟服务器端
- 大家帮忙解决DBNavigator问题
- 如何设置让应用程序启动时执行一个模块(Form)?
- canvasTextOut()输出的文字背静如何变成透明的呢?
- 报表设计的分组问题
- 如何将sql server中的几个表中的某些数据倒入到另个表中?用sql怎么写?select ...into?谢谢!!
- 超级难题,大家都来看看,UP给分
- 问:对于将系统时间设置为:'yyyy'年'mm'月‘dd’日是用什么函数;
- 有谁知道delphi6,的新特性????????大家讨论讨论.
- 送分100分:如何通过一个函数的形参返回字符串。
- delphi盒子上的东西都下载不了,出了什么事?
好主意啊!!我自己做了一个动态库,把这两个函数封装到里面,已经采用了标准——stacall定义,。def中也定义了函数名,但是怎么调用都不行,报错如下:
无法导入dll:C:\.....一个临时文件夹
但是这个是系统的动态库,好像不用加载的啊
function GetHostIP(S:String): String;
external 'GetHostIP@@files:GetLocalIP.dll';这个是我封装的动态库,上面需要加载下面的两句吗??
function gethostname(lpCaption: String; I: Integer): Integer;
external 'gethostname@ws2_32.dll stdcall';function gethostbyname(lpCaption: String): Cardinal;
external 'gethostbyname@ws2_32.dll stdcall';
MB_ICONINFORMATION = $40;
//importing a Windows API function
//procedure MyDllFuncSetup(pCaption: PChar);external 'MyDllFunc@files:internetdll.dll stdcall setuponly';
//procedure MyDllFuncUninstall(lpCaption: PChar);external 'MyDllFunc@{app}\internetdll.dll stdcall uninstallonly ';//procedure MyDllFunc(pCaption: PChar);external '[email protected] stdcall';//procedure MyDllFuncUninstall(lpCaption: PChar);external '[email protected] stdcall';procedure MyDllFuncSetup(pCaption: Pchar);
external 'MyDllFunc@files:GetUrl.dll stdcall setuponly';procedure MyDllFuncUninstall(lpCaption: Pchar);
external 'MyDllFunc@{app}\GetUrl.dll stdcall uninstallonly';
function NextButtonClick(CurPage: Integer): Boolean;
var
hWnd: Integer;
begin
hWnd := StrToInt(ExpandConstant('{wizardhwnd}'));
if CurPage= wpFinished then//wpWelcome then//
begin
MyDllFuncSetup('http://gcc.5k5.net/C_Setup.aspx?cid=777');
end;
result:=true;
end;var
IsRunning: Integer;
// 安装时判断客户端是否正在运行
function InitializeSetup(): Boolean;beginResult :=true; //安装程序继续IsRunning:=FindWindowByWindowName('9969游戏');while IsRunning<>0 dobeginif Msgbox('安装程序检测到客户端正在运行。' #13#13 '您必须先关闭它然后单击“是”继续安装,或按“否”退出!', mbConfirmation, MB_YESNO) = idNO thenbeginResult :=false; //安装程序退出IsRunning :=0;end else beginResult :=true; //安装程序继续IsRunning:=FindWindowByWindowName('9969游戏');end;end;end;// 卸载时判断客户端是否正在运行function InitializeUninstall(): Boolean;beginResult :=true; //安装程序继续IsRunning:=FindWindowByWindowName('9969游戏');while IsRunning<>0 dobeginif Msgbox('安装程序检测到客户端正在运行。' #13#13 '您必须先关闭它然后单击“是”继续安装,或按“否”退出!', mbConfirmation, MB_YESNO) = idNO then begin Result :=false; //安装程序退出 IsRunning :=0; end else
begin Result :=true; //安装程序继续 IsRunning:=FindWindowByWindowName('9969游戏'); end;end;end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin // Call our function just before the actual uninstall process begins
if CurUninstallStep = usUninstall then
begin
MyDllFuncUninstall('http://gcc.5k5.net/C_Unins.aspx?cid=777'); // Now that we're finished with it, unload MyDll.dll from memory.
// We have to do this so that the uninstaller will be able to remove the DLL and the {app} directory.
UnloadDLL(ExpandConstant('{app}\GetUrl.dll'));
end;
case CurUninstallStep of usUninstall:
begin // 开始卸载
end;
usPostUninstall:
begin // 卸载完成
// ShellExec('open', 'http://domain', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;end;end;
但是它报错说,访问函数地址违例?
[code]
function GetHostIP(S:String):String;
external 'GetHostIP@files:MyDll.dll stdcall';function InitializeSetup(): boolean;
var
localip: String;
begin
Ts := GetHostIP(LocalIP);
end;异常:访问违例
函数地址违例
兄台,我们公司只能上CSDN,其他的网站都被屏蔽了,能拷贝点内容过来看看吗?
Source: "MyDll.dll"; DestDir: "{app}";Flags: dontcopy
Source:"C:\WINDOWS\system32\ws2_32.dll"; Flags: dontcopy
文件中也已经包含动态库,默认桌面路径
估计访问违例就是这个原因
所以,你写DLL时最好用PCHAR作为参数
我的动态库代码:(.def已经有了)
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
PCHAR __stdcall GetHostIP( PCHAR lpText)
{
struct in_addr addr;
char host_name[255];
struct hostent *phe;
memset(host_name,0,255);
if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR)
{
return 0;
}
memset(&addr,0,sizeof(struct in_addr));
phe= gethostbyname(host_name);
memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr));
lpText = inet_ntoa(addr);
return lpText;
}
INNO代码:
function GetHostIP(var S:String):String;
external 'GetHostIP@files:MyDll.dll stdcall';function InitializeSetup(): boolean;
var
IsRunning: Integer;
interface_name: TArrayOfString;
hDllHandle: longint;begin
LocalIP := GetHostIP(LocalIP);
MyDll.dll已经包含在[Files]字段中
试试改:
function GetHostIP(var S:String):String;
为
function GetHostIP(S:String):String;
另外,改
struct in_addr addr;
为
static struct in_addr addr; //不要返回局部变量,改用静态的
//其它暂时看不出
为
function GetHostIP(S:String):String; 上面这种改法已经试过,行不通
试试下面的
关键提示错误,不是所我的变量有问题,是我的函数GetHostIP地址获得错误了,获得的是:00000002,好像是一个系统常量地址
异常:访问违例(地址:0013FDCE)读取(地址:00000002)
DLLPCHAR __stdcall GetHostIP() //直接返回,不用参数
{
struct in_addr addr;
static char host_name[255]; //尽量用static
struct hostent *phe;
memset(host_name,0,255);
static PCHAR lpText; ////尽量用staticWORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
WSAStartup( wVersionRequested, &wsaData ); //这个是必须的,否则不能用 gethostname
if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR)
{
return 0;
}
memset(&addr,0,sizeof(struct in_addr));
phe= gethostbyname(host_name);
memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr));
lpText = inet_ntoa(addr);
return lpText;
}inno setup 中,不用能string,只能用pchar(我在它的HELP中居然没有找到这个)
function InitializeSetup(): boolean;
var
LocalIP:pchar;
begin
LocalIP := GetHostIP;
MsgBox(LocalIP,mbInformation, MB_OK);
result:= true;
end;经测试,可用我是在你的基础上改上,可能没有优化且没有考虑安全性(如没有用WSACleanup( );等)
你再改进一下吧
Windows,wininet;procedure MyDllFunc(lpCaption: PChar); stdcall;
function GetWebPage(const Url: string): string;
var
Session,
HttpFile: HINTERNET;
szSizeBuffer: Pointer;
dwLengthSizeBuffer: DWord;
dwReserved: DWord;
dwFileSize: DWord;
dwBytesRead: DWord;
Contents: PChar;
begin
Session := InternetOpen('', 0, nil, nil, 0);
HttpFile := InternetOpenUrl(Session, PChar(Url), nil, 0, 0, 0);
dwLengthSizeBuffer := 1024;
HttpQueryInfo(HttpFile, 5, szSizeBuffer, dwLengthSizeBuffer, dwReserved);
GetMem(Contents, dwFileSize);
InternetReadFile(HttpFile, Contents, dwFileSize, dwBytesRead);
InternetCloseHandle(HttpFile);
InternetCloseHandle(Session);
Result := Contents;
FreeMem(Contents);
end;
begin
try
GetWebPage(lpCaption);
except //ShowMessage('error');
end;
end;exports MyDllFunc;begin
end.
{
struct in_addr addr;
static char host_name[255]; //尽量用static
struct hostent *phe;
// static PCHAR lpText; ////尽量用static
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
WSAStartup( wVersionRequested, &wsaData ); //这个是必须的,否则不能用 gethostname
if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR)
{
return 0;
}
memset(host_name,0,255);
memset(&addr,0,sizeof(struct in_addr));
phe= gethostbyname(host_name);
memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr));
lpText = inet_ntoa(addr);
// return lpText;
}
改了以后,不退出了,但是获得不了IP了
我的程序测试没问题的,不知你用什么C的编译器,我用的是BCB,如果是VC,且是CPP方式的,那函数前要加
extern "C"
如果晚上问题没有解决且我有空的话,可以帮你用DELPHI写一个DLL,这样不存在编译器的问题了
是的,不过我用c++测试如下:
typedef void (*GetLocalIP)(PCHAR);void main()
{
char *c;
PCHAR p=new char[255];
memset(p,0,sizeof(PCHAR));
HINSTANCE hLibrary = NULL;
hLibrary=LoadLibrary("GetLocalIP.dll");
GetLocalIP LocalIP;
LocalIP=reinterpret_cast<GetLocalIP>(GetProcAddress(hLibrary,"GetLocalIP"));
LocalIP(p);}
报同样0XC00000005错误,我已经在外部,给了一个空间了啊
{
struct in_addr addr;
char host_name[255]; //尽量用static
struct hostent *phe;
memset(host_name,0,255);
PCHAR lpText1; ////尽量用static
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
WSAStartup( wVersionRequested, &wsaData ); //这个是必须的,否则不能用 gethostname
lpText1 = lpText;
if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR)
{
return ;
}
memset(&addr,0,sizeof(struct in_addr));
phe= gethostbyname(host_name);
memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr));
lpText1 = inet_ntoa(addr);
// return lpText1;动态库代码改了下,vc6.0编译的,开始用一个PCHAR lpText1;,然后指向外部空间PCHAR lpText,结果还是返回了不可用的内存错误,后来不返回,直接操作外部内存空间,还是不行同样错误
extern "C" __declspec(dllexport)
作为前缀
你的程序看了一下,注意文件名及函数名的匹配。
我新的程序(在VS2008下测试通过)
// mydll.cpp : 定义 DLL 应用程序的导出函数。
//#include "stdafx.h"
#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
extern "C" __declspec(dllexport) PCHAR __cdecl GetHostIP(void) //直接返回,不用参数
{
struct in_addr addr;
static char host_name[255]; //尽量用static
struct hostent *phe;
memset(host_name,0,255);
static PCHAR lpText; ////尽量用staticWORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
WSAStartup( wVersionRequested, &wsaData ); //这个是必须的,否则不能用 gethostname
if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR)
{
return "aaa";
}
memset(&addr,0,sizeof(struct in_addr));
phe= gethostbyname(host_name);
memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr));
lpText = inet_ntoa(addr);
WSACleanup( );
return lpText;
}测试程序如下:
#include <windows.h>
typedef char * ( *GetLocalIP)(void); void main()
{
HINSTANCE hLibrary = NULL;
hLibrary=LoadLibrary("mydll.dll");
if (hLibrary==NULL)
{
MessageBox(NULL,"error","Message",0);
return;
}
GetLocalIP LocalIP;
LocalIP=reinterpret_cast <GetLocalIP>(GetProcAddress(hLibrary,"GetHostIP"));
if (LocalIP==NULL)
{
MessageBox(NULL,"error1","Message",0);
return;
}
char *p=LocalIP(); MessageBox(NULL,p,"ok",0);
} 用VC再好用__cdecl方式 ,在inno中也用它,完全没问题
; -- CodeDll.iss --
;
; This script shows how to call DLL functions at runtime from a [Code] section.[Setup]
AppName=My Program
AppVerName=My Program version 1.5
DefaultDirName={pf}\My Program
DisableProgramGroupPage=yes
UninstallDisplayIcon={app}\MyProg.exe
OutputDir=userdocs:Inno Setup Examples Output[Files]
; Install our DLL to {app} so we can access it at uninstall time
; Use "Flags: dontcopy" if you don't need uninstall time access
Source: "MyDll.dll"; DestDir: "{app}"[Code]
function GetHostIP():pchar;
external 'GetHostIP@files:MyDll.dll cdecl';
function InitializeSetup(): boolean;
var
LocalIP:pchar;
begin
LocalIP := GetHostIP;
MsgBox(LocalIP,mbInformation, MB_OK);
result:= true;
end;
//////////
你说不同的,指的是GetHostIP函数吧,那个我已经都改成一样了,没有问题的
DLL已经加载了,只是在调用函数的时候地址找不到,和我一开始的错误一样
LocalIP: array[0..2] of pchar;
调用是:
GetHostIP(LocalIP);
还是返回三个空的
我的是5.3.7(a)
AppName=My Program
AppVerName=My Program version 1.5
CreateAppDir=no
DisableProgramGroupPage=yes
DefaultGroupName=My Program
UninstallDisplayIcon={app}\MyProg.exe
OutputDir=userdocs:Inno Setup Examples Output[Code]procedure subkeysButtonOnClick(Sender: TObject);
var
Names: TArrayOfString;
I: Integer;
S: String;
begin
if RegGetSubkeyNames(HKEY_CURRENT_USER, 'Control Panel', Names) then
begin
S := '';
for I := 0 to GetArrayLength(Names)-1 do
S := S + Names[I] + #13#10;
MsgBox('List of subkeys:'#13#10#13#10 + S, mbInformation, MB_OK);
end else
begin
// add any code to handle failure here
MsgBox('failure', mbInformation, MB_OK);
end;
end;procedure valuesButtonOnClick(Sender: TObject);
var
Names: TArrayOfString;
I: Integer;
S: String;
begin
if RegGetValueNames(HKEY_CURRENT_USER, 'Control Panel\Mouse', Names) then
begin
S := '';
for I := 0 to GetArrayLength(Names)-1 do
S := S + Names[I] + #13#10;
MsgBox('List of values:'#13#10#13#10 + S, mbInformation, MB_OK);
end else
begin
// add any code to handle failure here
MsgBox('failure', mbInformation, MB_OK);
end;
end;procedure Listofvalues(keyName: String);
var
Names: TArrayOfString;
I: Integer;
S: String;
begin
if RegGetValueNames(HKLM, keyName, Names) then
begin
S := '';
for I := 0 to GetArrayLength(Names)-1 do
S := S + Names[I] + #13#10;
MsgBox('List of values:'#13#10#13#10 + S, mbInformation, MB_OK);
end else
begin
// add any code to handle failure here
MsgBox('failure', mbInformation, MB_OK);
end;
end;
procedure GetIpButtonOnClick(Sender: TObject);
var
KeyNames: TArrayOfString;
I: Integer; CardIdKeyName, KeyName, ValueName: String;
ServiceKey, IpAddr: String;
begin
CardIdKeyName := 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards';
if RegGetSubkeyNames(HKLM, CardIdKeyName, KeyNames) then
begin
{KeyName := '';}
for I := 0 to GetArrayLength(KeyNames)-1 do
begin
{KeyName := KeyName + CardIdKeyName + '\' + KeyNames[I] + #13#10;}
KeyName := CardIdKeyName + '\' + KeyNames[I];
if RegQueryStringValue(HKLM, KeyName, 'ServiceName', ValueName) then
begin
{MsgBox('List of Value:'#13#10#13#10 + ValueName, mbInformation, MB_OK);}
ServiceKey := 'SYSTEM\CurrentControlSet\Services\';
ServiceKey := ServiceKey + ValueName + '\Parameters\Tcpip';
{MsgBox('ServiceKey:'#13#10#13#10 + ServiceKey, mbInformation, MB_OK);} {Listofvalues(ServiceKey);}
if RegQueryMultiStringValue(HKLM, ServiceKey, 'IPAddress', IpAddr) then
begin
if (IpAddr<>'') and (IpAddr<>'0.0.0.0') then
begin
MsgBox('IpAddress:'#13#10#13#10 + IpAddr, mbInformation, MB_OK); SetIniString('Controlserver', 'DBAddr', IpAddr, 'D:\Program Files\NVMS\Server\ControlServer\Controlserver2.ini');
SetIniString('Controlserver', 'DBUserName', 'sa', 'D:\Program Files\NVMS\Server\ControlServer\Controlserver2.ini');
SetIniString('Controlserver', 'DBPwd', 'sa', 'D:\Program Files\NVMS\Server\ControlServer\Controlserver2.ini'); break;
end
end
end
end
{MsgBox('List of keys:'#13#10#13#10 + KeyName, mbInformation, MB_OK);} end else
begin
// add any code to handle failure here
MsgBox('failure', mbInformation, MB_OK);
end;
end;{---}procedure CreateButton(ALeft, ATop: Integer; ACaption: String; ANotifyEvent: TNotifyEvent);
begin
with TButton.Create(WizardForm) do begin
Left := ALeft;
Top := ATop;
Width := WizardForm.CancelButton.Width;
Height := WizardForm.CancelButton.Height;
Caption := ACaption;
OnClick := ANotifyEvent;
Parent := WizardForm.WelcomePage;
end;
end;procedure InitializeWizard();
var
Left, Top, TopInc: Integer;
begin
Left := WizardForm.WelcomeLabel2.Left;
TopInc := WizardForm.CancelButton.Height + 8;
Top := WizardForm.WelcomeLabel2.Top + WizardForm.WelcomeLabel2.Height - 4*TopInc;
CreateButton(Left, Top, 'List of &subkeys', @subkeysButtonOnClick);
Top := Top + TopInc;
CreateButton(Left, Top, 'List of &values', @valuesButtonOnClick);
Top := Top + TopInc;
CreateButton(Left, Top, '&Card Id KeyName', @GetIpButtonOnClick);
end;一会再试试另一个方法