我想在程序中将一个目录设为网络只读共享,该怎么做?

解决方案 »

  1.   

    局域网中文件夹的共享 Windows NT/2000/XP   
    局域网中文件夹的共享 Windows NT/2000/XP在局域网中通过程序实现文件夹的共享,就我知道的应该至少有两种实现方式。一是修改注册表,但是这种方法存在的问题也是很明显的,必须重起机器才能生效。二就是利用 Windows Api函数 NetShareAdd ,通过这个函数我们可以很容易的实现文件夹的共享,而且无需重起计算机。使用这个函数时我们必须注意的是在 Windows NT/2000/XP 和 Windows 95/98/Me 下用法是有很大差别的,这一点我相信大家都有体会,明明在 95 或 98 下实现好好的,可是一到 NT 下就出问题。其实不光是各位仁兄,我早就提出过这个问题,怎奈一直都没有解决掉。现在好了,希望读完后能给大家一点点帮助。Windows 95/98/Me 下 NetShareAdd 函数声明在 SVRAPI.DLL 动态连接库中,而在 2000/XP/NT 下声明在 NETAPI32.DLL 动态连接库中。所以我们在不同的操作系统下一定要注意调用不同的 DLL 库。这些函数详细的声明,在新版 MSDN 2002 中有介绍。由于在Delphi中没有声明这些函数和他们的参数所以我们要想实现这个函数还必须自己声明(可能delphi 有声明我不知道在那个单元中)。顺便说一句,我使用的是 delphi5.0 版,可惜他的帮助文件实在是太陈旧了,还是先看看 MSDN 2002 中关于 NetShareAdd 函数的声明巴!Windows NT/2000/XP: NET_API_STATUS NetShareAdd( 
    LPWSTR servername, //对应 Delphi 中 PWideChar
    DWORD level, //对应 DELPHI 中 DWOED
    LPBYTE buf, //对应 DELPHI 中 PBYTE
    LPDWORD parm_err // 对应 DELPHI 中 PDWORD 
    );
    Windows 95/98/Me: 下面的对应参数就不用说了吧!可以直接看看DELPHI帮助文件。extern API_FUNCTION
    NetShareAdd(
    const char FAR * pszServer, 
    short sLevel, 
    const char FAR * pbBuffer, 
    unsigned short cbBuffer 
    ); 特别强调:我们在声明上面的函数时,函数参数一定要写对,也就是一定要正确对应到DELPHI 自己的类型上。不然函数功能无法实现,这一点我已经尝试了。之所以在NT 下实现不了主要还是,参数类型对应的不对。我们还需要声明一个记录类型,在98/95/me 和 nt/2000/xp下声明如下: 
    Windows NT/2000/XP: SHARE_INFO_2 和 SHARE_INFO_502 结构 
    Windows 95/98/Me: share_info_50 结构对以上这个结构的声明更应该注意参数类型的正确对应。原始声明如下:typedef struct _SHARE_INFO_502 {
    LPWSTR shi502_netname; // PWideChar; 
    DWORD shi502_type; // DWORD; 
    LPWSTR shi502_re; // PWideChar;
    DWORD shi502_permissions; // DWORD; 
    DWORD shi502_max_uses; // DWORD;
    DWORD shi502_current_uses; //DWORD; 
    LPWSTR shi502_path; //PWideChar; 
    LPWSTR shi502_passwd; // PWideChar; 
    DWORD shi502_reserved; // DWORD ;
    // PSECURITY_DESCRIPTOR ;一般设为 Nil
    PSECURITY_DESCRIPTOR shi502_security_descriptor;
    } SHARE_INFO_502, *PSHARE_INFO_502, *LPSHARE_INFO_502;对应 Delphi 纪录声明如下:一定要注意参数类型的正确对应,如果你把PWideChar 声明为 pchar 函数将无法实现此功能,我已经尝试了,你可以再试试,至于原因是什么,我也不太清楚。type 
    TSHARE_INFO_502 = record
    shi502_netname: PWideChar;
    shi502_type: DWORD;
    shi502_re: PWideChar;
    shi502_permissions: DWORD;
    shi502_max_uses: DWORD;
    shi502_current_uses: DWORD;
    shi502_path: PWideChar;
    shi502_passwd: PWideChar;
    shi502_reserved: DWORD;
    shi502_security_descriptor: PSECURITY_DESCRIPTOR;
    end;下面是完成的程序代码,其中有两部分,主程序和单元文件。运行环境 windows 2000 Ads 开发工具 Delphi5.0 。运行通过。unit Share; 
    interface
    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls,FileCtrl,My_Share;
    type
    TFormShare = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    BtSelect: TButton;
    EditDir: TEdit;//文件共享目录
    EditSharename: TEdit; //共享名称
    EditInfo: TEdit;//备注
    Button1: TButton;
    Button2: TButton;
    procedure BtSelectClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    private
    { Private declarations }
    public
    { Public declarations }
    end; 
    var
    FormShare: TFormShare;
    implementation{$R *.DFM} 
    procedure TFormShare.BtSelectClick(Sender: TObject);
    var
    directory: string;
    begin
    if SelectDirectory('选择一个目录','', directory) then
    EditDir.Text := directory;
    end;procedure TFormShare.Button1Click(Sender: TObject);
    begin
    if EditDir.Text = '' then
    begin
    Application.MessageBox('请先选择一个目录!', '共享', MB_ICONINFORMATION + MB_OK);
    BtSelect.Click;
    Exit;
    end;
    if EditSharename.Text = '' then
    begin
    Application.MessageBox('请先输入共享名称!', '共享', MB_ICONINFORMATION + MB_OK);
    EditSharename.SetFocus;
    Exit;
    end;
    ShareResource('eengi',EditDir.Text,EditSharename.Text,EditInfo.Text);
    {注意:如果在共享目录名称后面添加 $ 符号,共享后在网络邻居里看不到此文件夹但实际上已经共享了,你可以在本地看到}
    end; 
    end.以下是单元文件: 
    unit My_Share;
    interface
    uses
    Windows,Sysutils ;
    type
    //纪录类型声明,注意参数类型的正确对应,最好别看 delphi 的帮助,引起误导
    TSHARE_INFO_502 = record
    shi502_netname: PWideChar;
    shi502_type: DWORD;
    shi502_re: PWideChar;
    shi502_permissions: DWORD;
    shi502_max_uses: DWORD;
    shi502_current_uses: DWORD;
    shi502_path: PWideChar;
    shi502_passwd: PWideChar;
    shi502_reserved: DWORD;
    shi502_security_descriptor: PSECURITY_DESCRIPTOR;
    end;
    //添加共享
    function NetShareAdd(servername:Widestring; level: DWORD; Buf: PBYTE;
    var parm_err: PDWORD ): DWORD; stdcall;
    //删除共享
    function NetShareDel(ServerName:Widestring; NetName: Widestring;
    Reserved: DWord): Integer; StdCall;
    const
    {共享类型}
    STYPE_DISKTREE = 0 ;
    STYPE_PRINTQ = 1 ;
    STYPE_DEVICE = 2 ;
    STYPE_IPC = 3 ;
    {访问权限}
    ACCESS_READ = 0 ;
    ACCESS_WRITE = 1 ;
    ACCESS_CREATE = 2 ;
    ACCESS_EXEC = 3 ;
    ACCESS_DELETE = 4 ;
    ACCESS_ALL = 7 ;//自己声明的函数,为了调用方便,参数就不用说明了吧!
    function ShareResource(ServerName,FilePath,NetName, Re : string): Integer;
    //function DeleteShare(ServerName: string; NetName: string): Integer;
    implementation
    //注意在 windows95/98/me 下面 dll 库是 SVRAPI.DLL ,而且参数类型也要随之改变的吆!
    function NetShareAdd; external 'netapi32.DLL' name 'NetShareAdd';
    function NetShareDel; external 'netapi32.DLL' name 'NetShareDel';function ShareResource(ServerName,FilePath,NetName, Re : string): Integer;var 
    ShInfo: TSHARE_INFO_502; 
    parm_err:PDWORD; 
    _FilePath,_NetName, _Re : PWideChar ; 
    _ServerName : Pchar ; 
    begin 
    GetMem(_ServerName,255) ; //分配内存
    GetMem(_FilePath,255);
    GetMem(_NetName,255);
    GetMem(_Re,255);
    StringToWideChar(FilePath,_FilePath,255); //字符串转换,一定要转换正确
    StringToWideChar(NetName,_NetName,255);
    StringToWideChar(Re,_Re,255);
    strpcopy(_ServerName,ServerName);
    //开始创建结构
    with ShInfo do
    begin
    shi502_netname := _NetName;
    shi502_type := STYPE_DISKTREE ;
    shi502_re := _Re ;
    shi502_max_uses := $FFFFFFFF;
    shi502_current_uses := 10;
    shi502_path := _FilePath;
    shi502_passwd := nil;
    shi502_reserved := 0;
    shi502_security_descriptor := nil;
    shi502_permissions := ACCESS_ALL;
    end;
    try
    Result := NetShareAdd(_ServerName, 502, @ShInfo, parm_err);
    Finally // 别忘了释放内存
    FreeMem(_ServerName,255);
    FreeMem(_FilePath,255);
    FreeMem(_NetName,255);
    FreeMem(_Re,255);
    end;
    end;
    end.总结:运行完程序后,相信大家和我有同样的感觉,其实成功就在眼前,就差一点,可是就这一点也很难跨越。程序之所以一直实现不了,恐怕我们都没有考虑参数类型声明是否正确。不过我应该非常感谢csdn 上“绝对菜鸟”的回复。要不是他的程序,恐怕我还在等待中探索
      

  2.   

    奇怪,我用这个方法,共享出的目录不管选什么共享类型,都是有完全控制权,好像shi502_permissions 这参数没用
      

  3.   

    我在网上找到一个bcb的例子,你看看修改一下。 这是建立和删除共享目录的例子,我没有试验过,看起来它可以支持每一种Windows版本。 
    #include <lmcons.h> 
    #include <lmshare.h> 
    #include <lmaccess.h> typedef NET_API_STATUS (NET_API_FUNCTION *LMS_NETSHAREDEL)(IN LPWSTR servername, IN LPWSTR netname, IN DWORD reserved); 
    typedef NET_API_STATUS (NET_API_FUNCTION *LMS_NETSHAREADD)(IN LPWSTR servername, IN DWORD level, IN LPBYTE buf, OUT LPDWORD parm_err); 
    typedef DWORD (WINAPI *SVR_NETSHAREDEL)(const char FAR *pszServer, const char FAR *pszNetName, unsigned short usReserved); 
    typedef DWORD (WINAPI *SVR_NETSHAREADD)(const char FAR * pszServer, short sLevel, const char FAR * pbBuffer, unsigned short cbBuffer); LMS_NETSHAREDEL pLMSNetShareDel; 
    LMS_NETSHAREADD pLMSNetShareAdd; 
    SVR_NETSHAREDEL pSVRNetShareDel; 
    SVR_NETSHAREADD pSVRNetShareAdd; #define SHI50F_RDONLY 0x0001 
    #define SHI50F_FULL 0x0002 
    #define SHI50F_DEPENDSON (SHI50F_RDONLY|SHI50F_FULL) 
    #define SHI50F_ACCESSMASK (SHI50F_RDONLY|SHI50F_FULL) 
    #define SHI50F_PERSIST 0x0100 
    #define SHI50F_SYSTEM 0x0200 HINSTANCE ghDll_NetApi32; 
    HINSTANCE ghDll_SvrApi; struct share_info_50 { 
    char shi50_netname[LM20_NNLEN+1]; /* share name */ 
    unsigned char shi50_type; /* see below */ 
    unsigned short shi50_flags; /* see below */ 
    char FAR * shi50_re; /* ANSI comment string */ 
    char FAR * shi50_path; /* shared resource */ 
    char shi50_rw_password[SHPWLEN+1]; /* read-write password (share-level security) */ 
    char shi50_ro_password[SHPWLEN+1]; /* read-only password (share-level security) */ 
    }; /* share_info_50 */ struct share_info_2 { 
    char shi2_netname[LM20_NNLEN+1]; 
    char shi2_pad1; 
    unsigned short shi2_type; 
    char FAR * shi2_re; 
    unsigned short shi2_permissions; 
    unsigned short shi2_max_uses; 
    unsigned short shi2_current_uses; 
    char FAR * shi2_path; 
    char shi2_passwd[SHPWLEN+1]; 
    char shi2_pad2; 
    }; /* share_info_2 */ /*初始化动态链接库*/ 
    int InitDynamicLibraries(BOOL bWinNT) /* initialize dynamic libraries */ 
    { if(bWinNT) { 
    ghDll_NetApi32 = LoadLibrary("NETAPI32.DLL"); 
    if(ghDll_NetApi32==NULL) return -1; 
    pLMSNetShareDel = (LMS_NETSHAREDEL)GetProcAddress(ghDll_NetApi32, "NetShareDel"); 
    pLMSNetShareAdd = (LMS_NETSHAREADD)GetProcAddress(ghDll_NetApi32, "NetShareAdd"); 
    } else { 
    ghDll_SvrApi = LoadLibrary("SVRAPI.DLL"); 
    if(ghDll_SvrApi==NULL) return -1; 
    pSVRNetShareDel = (SVR_NETSHAREDEL)GetProcAddress(ghDll_SvrApi, "NetShareDel"); 
    pSVRNetShareAdd = (SVR_NETSHAREADD)GetProcAddress(ghDll_SvrApi, "NetShareAdd"); 
    } return 0; 
    } /*释放动态链接库*/ 
    int KillDynamicLibraries(void) /* kill dynamic libraries */ 

    if(ghDll_NetApi32!=NULL) 
    FreeLibrary(ghDll_NetApi32); 
    if(ghDll_SvrApi!=NULL) 
    FreeLibrary(ghDll_SvrApi); return 0; 
    } /*创建共享*/ 
    BOOL NetExportAdd(BOOL bWinNT, char* szPath, char* szShellName) /* add a net share */ 

    DWORD ret; CharUpper(szPath); 
    CharUpper(szShellName); if(bWinNT) { 
    SHARE_INFO_502 shinfo; 
    WCHAR wsvPath[MAX_PATH+1],wsvNetName[256],wsvRe,wsvPasswd; 
    MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szPath,-1,wsvPath,MAX_PATH+1); 
    MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szShellName,-1,wsvNetName,256); 
    wsvRe=(WCHAR)0; 
    wsvPasswd=(WCHAR)0; shinfo.shi502_netname=(LPTSTR)wsvNetName; 
    shinfo.shi502_type=STYPE_DISKTREE; 
    shinfo.shi502_re=(LPTSTR)&wsvRe; 
    shinfo.shi502_permissions=ACCESS_ALL; 
    shinfo.shi502_max_uses=-1; 
    shinfo.shi502_current_uses=0; 
    shinfo.shi502_path=(LPTSTR)wsvPath; 
    shinfo.shi502_passwd=(LPTSTR)&wsvPasswd; 
    shinfo.shi502_reserved=0; 
    shinfo.shi502_security_descriptor=NULL; 
    ret=pLMSNetShareAdd(NULL, 502, (LPBYTE)&shinfo, NULL); } else { 
    struct share_info_50 shinfo50; lstrcpyn(shinfo50.shi50_netname,szShellName,LM20_NNLEN+1); 
    shinfo50.shi50_type=STYPE_DISKTREE; 
    shinfo50.shi50_flags=SHI50F_FULL | SHI50F_SYSTEM| SHI50F_PERSIST; 
    shinfo50.shi50_re=""; 
    shinfo50.shi50_path=szPath; 
    shinfo50.shi50_rw_password[0]=0; 
    shinfo50.shi50_ro_password[0]=0; 
    ret=pSVRNetShareAdd(NULL, 50, (char *)&shinfo50, sizeof(struct share_info_50)); 
    } if(ret==0) 
    return true; 
    else 
    return false; 
    } /*删除共享*/ 
    BOOL NetExportDelete(BOOL bWinNT, char *szShellName) /* delete a net share */ 

    DWORD ret; CharUpper(szShellName); if(bWinNT) { 
    WCHAR wsvNetName[256]; 
    MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szShellName,-1,wsvNetName,256); 
    ret=pLMSNetShareDel(NULL,wsvNetName,0); 
    } else { 
    ret=pSVRNetShareDel(NULL,szShellName,0); 
    } if(ret==0) 
    return true; 
    else 
    return false; 
      

  4.   

    能直接给出DELPHI的代码吗?C的看不懂
      

  5.   

    http://expert.csdn.net/Expert/topic/2168/2168863.xml?temp=.1706354
      

  6.   

    好像结了贴也不知怎么回事,有没有程序发给我一个
    [email protected]