如何检测局域网内哪些机器安装了SQL Server2000?(34分)

  • 主题发起人 主题发起人 Beyond2002
  • 开始时间 开始时间
B

Beyond2002

Unregistered / Unconfirmed
GUEST, unregistred user!
如题:如何检测局域网内哪些机器安装了SQL Server2000?
 
有没有办法
 
找一台安装有sqlserver的机器并进入数据库企业管理器,在某个sql server组上点击右键,选择新建SQL SERVER注册,便可看到局域网内所有提供服务的SQL SERVER 服务器名称
 
我想通过程序实现!
 
很简单牙,循环找局与网里机器,然后分别查看他们每个机器上注册表中有SQLSERVER注册过就行了,详细代码就不用说了,找找帮助,这些功能就实现了
 
uses ComObj;
GetSQLServerList(Memo1.Lines);

function GetSQLServerList(List: TStrings): Boolean;
var
SQLServer: Variant;
ServerList: Variant;
i: Integer;
begin
Result:=False;

if not Assigned(List) then
Exit;
List.Clear;

try
try
SQLServer:=CreateOleObject('SQLDMO.Application');
ServerList:=SQLServer.ListAvailableSQLServers;
for i:=1 to ServerList.Count do
List.Add(ServerList.Item(i));

Result:=True;
except
on E: Exception do;
end;
finally
ServerList:=NULL;
SQLServer:=NULL;
end;
end;
 
使用下面的函数。
Function GetSQLServerList(var List: Tstringlist): boolean;
var
i: integer;
sRetValue: String;
SQLServer: Variant;
ServerList: Variant;
begin
Result := False;
List.Clear;
try
SQLServer := CreateOleObject('SQLDMO.Application');
ServerList := SQLServer.ListAvailableSQLServers;
for i := 1 to Serverlist.Count do
list.Add (Serverlist.item(i));
Result := True;
Finally
SQLServer := NULL;
ServerList := NULL;
end;
end;
 
试了一下:我的机器装的是SQL Server2000,可以搜索到本机的,但是不能搜索到局域网上装有SQLServer7的机器
另外是否在搜索的机器上必须安装SQLServer?如果是的话,那只能想别的办法了!
 
用createoleobject的方法可以取到,但是速度很慢!
 
SQL默认会打开端口 1433 或者 sql/query管道 (在客户端连接工具中可看到)
尝试打开这些端口和管道,看是否有存在()
SQL Server7同样会存在这些的
 
与SQLServer7不同,SQL Server2000的端口一般不是固定的,再说端口
可以修改
 
那恐怕这个方法不行了...(除非有某个固定的服务存在才行,要不然...)
btw
CreateOleObject其实等同于在服务管理器中看到的
而既然服务管理器能够看到的,我想那么肯定有这个固定的服务存在才行
你可以先更改某个SQL Server2000的端口和管道名称,看是否还能在服务管理器中看到
,我想可能也是看不到的
 
用CreateOleObject的方法确实可以检测到,但是前提是本机上也已经安装了sql server,否则CreateOleObject会出错
 
起码1433会有的。port再怎么改总要一个固定port做通讯。
 
(上面提到的是代码实现的方法,若在客户机上没有安装SQLDMO.Application则不能用!)
考虑到一般sql server 主机上一般都安装了SQLDMO.Application,因此想到了用sql语句直
接取回结果! 其语句如下:(我现在一直都采用这方法,效果很好)

//add chji 2002-12-11
//取得目标机上局网内的SQL主机
function GetSQlList(AdoQuery:Tadoquery): String;
begin
AdoQuery.Close;
AdoQuery.SQL.Clear;
AdoQuery.SQL.Add('DECLARE @SqlServer int,@ListAvailableSQLServers int');
AdoQuery.SQL.Add('DECLARE @Count int,@i int,@str varchar(500),@str2 varchar(500)');
AdoQuery.SQL.Add('DECLARE @hr int,@src varchar(255), @desc varchar(255)');

AdoQuery.SQL.Add('EXEC @hr = sp_OACreate ''SQLDMO.Application'', @SqlServer OUT');
AdoQuery.SQL.Add('IF @hr <> 0');
AdoQuery.SQL.Add('BEGIN');
AdoQuery.SQL.Add(' EXEC sp_OAGetErrorInfo @SqlServer, @src OUT, @desc OUT');
AdoQuery.SQL.Add(' SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc');
AdoQuery.SQL.Add(' RETURN');
AdoQuery.SQL.Add('END');
AdoQuery.SQL.Add('EXEC @hr = sp_OAMethod @SqlServer, ''ListAvailableSQLServers'',@ListAvailableSQLServers out');
AdoQuery.SQL.Add('IF @hr <> 0');
AdoQuery.SQL.Add(' begin');
AdoQuery.SQL.Add(' EXEC sp_OAGetErrorInfo @ListAvailableSQLServers, @src OUT, @desc OUT');
AdoQuery.SQL.Add(' SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc');
AdoQuery.SQL.Add(' RETURN');
AdoQuery.SQL.Add('end');
AdoQuery.SQL.Add('EXEC @hr = sp_OAGetProperty @ListAvailableSQLServers, ''Count'',@Count out');
AdoQuery.SQL.Add('IF @hr <> 0');
AdoQuery.SQL.Add('BEGIN');
AdoQuery.SQL.Add(' EXEC sp_OAGetErrorInfo @ListAvailableSQLServers, @src OUT, @desc OUT');
AdoQuery.SQL.Add(' SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc');
AdoQuery.SQL.Add(' RETURN');
AdoQuery.SQL.Add('END');
AdoQuery.SQL.Add('set @i=1');
AdoQuery.SQL.Add('set @str=''''');
AdoQuery.SQL.Add(' while @i<=@count');
AdoQuery.SQL.Add(' begin');
AdoQuery.SQL.Add(' set @str2=''Item(''+cast(@i as varchar)+'')''');
AdoQuery.SQL.Add(' EXEC @hr = sp_OAGetProperty @ListAvailableSQLServers, @str2,@str2 out');
AdoQuery.SQL.Add(' IF @hr <> 0');
AdoQuery.SQL.Add(' BEGIN');
AdoQuery.SQL.Add(' EXEC sp_OAGetErrorInfo @ListAvailableSQLServers, @src OUT, @desc OUT');
AdoQuery.SQL.Add(' SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc');
AdoQuery.SQL.Add(' break');
AdoQuery.SQL.Add(' END');
AdoQuery.SQL.Add(' if @str=''''');
AdoQuery.SQL.Add(' set @str=@str2');
AdoQuery.SQL.Add(' else');
AdoQuery.SQL.Add(' set @str=@str+'',''+@str2');
AdoQuery.SQL.Add(' set @i=@i+1');
AdoQuery.SQL.Add(' end');
AdoQuery.SQL.Add('exec sp_OADestroy @ListAvailableSQLServers');
AdoQuery.SQL.Add('exec sp_OADestroy @SqlServer');
AdoQuery.SQL.Add(' select @str as A');
AdoQuery.Open;
result:=AdoQuery.Fieldbyname('a').asstring;
end;


 
如果没记错的话
我记得Windows有一种服务的概念
就是根据一个固定的名称就可以查找到相应的端口从而进行连接
(看自Delphi的某个TCP控件的属性里面 好像是D6有D7没有的,TTcpSocket)
由 Machine和 (ServiceName 或 IPPort)确定连接
谁有D6可以查看一下,不知道SQL Server是不是会这样找到机器的
 
对了,好象是udp/1434
固定的。
 
我在几台机器上安装SQLServer2000,其端口号都不相同,所以firstrose的方法不适用
 
如果SQL Server的客户端工具可以找到,按理用程序就可以实现。
关键是SQL Server的客户端工具是如何找到的?
说不定它提供了一些动态连接库可以使用。
 
no,no
为实现动态端口,必须有个固定的方法以取得使用的port。就是通过udp/1434通讯。
如果你看过那个376字节的蠕虫的分析文章,你就会明白的。
 
后退
顶部