1. 程式人生 > >程式碼連線內網共享磁碟WNetCancelConnection();WNetAddConnection2()

程式碼連線內網共享磁碟WNetCancelConnection();WNetAddConnection2()

前言

如果你能看到本篇部落格說明你應該是對網路磁碟對映有所瞭解的,如果你不瞭解網路磁碟對映而是通過PathFileExists();WNetCancelConnection();WNetAddConnection2()這三個函式找到本部落格的,可以點選連結瞭解下網路磁碟對映

https://baike.baidu.com/item/%E6%98%A0%E5%B0%84%E7%BD%91%E7%BB%9C%E9%A9%B1%E5%8A%A8%E5%99%A8/10581942

準備工作

要實現該功能需要用到PathFileExists();WNetCancelConnection();WNetAddConnection2()

這三個函式

WNetCancelConnection();WNetAddConnection2()這兩個函式需要包含標頭檔案#include <WinNetWk.h>且需要引入庫

#pragma comment(lib, "shlwapi.lib")不然編譯時會出現如下錯誤:

error LNK2019: 無法解析的外部符號 [email protected],該符號在函式 "void __cdecl WriteLogFile(char const *)" ([email protected]@[email protected]) 中被引用

error LNK2019: 無法解析的外部符號

[email protected],該符號在函式 "void __cdecl Text_PathFileExists(void)" ([email protected]@YAXXZ) 中被引用

函式介紹

如此前置標頭檔案跟庫都已經準備好了,下面到三個函式(如果不是很想具體瞭解函式,就想直接運用的可以跳過這一段,直接去看程式碼)

PathFileExists()

看一下MSDN的解釋:Determines whether a path to a file system object such as a file or directory is valid

翻譯過來就是:確定一個檔案系統物件的路徑,例如檔案或目錄是否有效

Syntax

BOOL PathFileExists(      
    LPCTSTR pszPath
);

Parameters

pszPath

[in] A pointer to a null-terminated string of maximum length MAX_PATH that contains the full path of the object to verify.

一個指向空終止的最長長度maxpath字串的指標,該字串包含要驗證的物件的完整路徑

Return Value

Returns TRUE if the file exists, or FALSE otherwise. Call GetLastError for extended error information.
如果檔案存在,則返回TRUE;否則返回FALSE。呼叫GetLastError來擴充套件錯誤資訊

Remarks

This function tests the validity of the path.

A path specified by Universal Naming Convention (UNC) is limited to a file only; that is, \\server\share\file is permitted. A UNC path to a server or server share is not permitted; that is, \\server or \\server\share. This function returns FALSE if a mounted remote drive is out of service.

這個函式測試路徑的有效性。
由通用命名約定(UNC)指定的路徑僅限一個檔案;也就是說,允許伺服器共享檔案。不允許向伺服器或伺服器共享的UNC路徑;也就是說,伺服器或伺服器共享。如果掛載的遠端驅動器停止服務,該函式返回FALSE。

這是MSDN對該函式的介紹,其實該函式使用起來很簡單,例:

PathFileExistsA("Z:");該語句就可以測試你的電腦當前是否存在"Z:"盤這個虛擬磁碟 

WNetCancelConnection()

該函式取消現有網路連結,及如果目標磁碟已經連線上了網路中共享的資料夾,這個函式會讓其斷開連結

MSDN中原話:The WNetCancelConnection function cancels an existing network connection

翻譯過來是:WNetCancelConnection函式取消現有的網路連線

Syntax

DWORD WNetCancelConnection(
  __in  LPCTSTR lpName,
  __in  BOOL fForce
);

Parameters

lpName

Pointer to a constant null-terminated string that specifies the name of either the redirected local device or the remote network resource to disconnect from.

When this parameter specifies a redirected local device, the function cancels only the specified device redirection. If the parameter specifies a remote network resource, only the connections to remote networks without devices are canceled.

指標指向一個常量終止的字串,它指定重定向本地裝置的名稱或斷開連線的遠端網路資源的名稱。
當該引數指定重定向的本地裝置時,該函式僅取消指定的裝置重定向。如果引數指定了遠端網路資源,那麼只有與沒有裝置的遠端網路的連線被取消

fForce

Specifies whether or not the disconnection should occur if there are open files or jobs on the connection. If this parameter is FALSE, the function fails if there are open files or jobs.

指定如果連線上有開啟的檔案或作業,是否應該發生斷開。如果這個引數是假的,如果有開啟的檔案或作業,函式就會失敗

Return Value

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is a system error code, such as one of the following values.

如果函式成功,返回值是noerror。
如果函式失敗,返回值就是一個系統錯誤程式碼,例如下列值之一

Return code Description

ERROR_BAD_PROFILE

The user profile is in an incorrect format.

使用者配置檔案的格式不正確

ERROR_CANNOT_OPEN_PROFILE

The system is unable to open the user profile to process persistent connections.

系統無法開啟使用者配置檔案來處理持久連線

ERROR_DEVICE_IN_USE

The device is in use by an active process and cannot be disconnected.

該裝置處於活動過程中,不能斷開連線

ERROR_EXTENDED_ERROR

A network-specific error occurred. To obtain a description of the error, call the WNetGetLastError function.

出現了一個特定於網路的錯誤。要獲得錯誤的描述,請呼叫WNetGetLastError函式

ERROR_NOT_CONNECTED

The name specified by the lpName parameter is not a redirected device, or the system is not currently connected to the device specified by the parameter.

lpName引數指定的名字不是重定向裝置,或者系統目前沒有連線到引數指定的裝置

ERROR_OPEN_FILES

There are open files, and the fForce parameter is FALSE.

有開啟的檔案,fForce引數是假的

Remarks

Windows Server 2003 and Windows XP:  The WNet functions create and delete network drive letters in the MS-DOS device namespace associated with a logon session because MS-DOS devices are identified by AuthenticationID. (An AuthenticationID is the locally unique identifier, or LUID, associated with a logon session.) This can affect applications that call one of the WNet functions to create a network drive letter under one user logon, but query for existing network drive letters under a different user logon. An example of this situation could be when a user's second logon is created within a logon session, for example, by calling the CreateProcessAsUser function, and the second logon runs an application that calls the GetLogicalDrives function. GetLogicalDrives does not return network drive letters created by a WNet function under the first logon. Note that in the preceding example the first logon session still exists, and the example could apply to any logon session, including a Terminal Services session. For more information, see Defining an MS-DOS Device Name.
Windows Server 2003和Windows XP:WNet功能在與登入會話相關聯的MS-DOS裝置名稱空間中建立和刪除網路驅動器字母,因為MS-DOS裝置是由AuthenticationID標識的。(AuthenticationID是與登入會話相關聯的本地唯一識別碼或LUID。)這可能會影響呼叫WNet函式之一的應用程式,在一個使用者登入下建立一個網路驅動器字母,但是在不同的使用者登入下查詢現有的網路驅動器字母。這種情況的一個例子是,當用戶的第二次登入在徽標中建立時

 該函式使用也不難:WNetCancelConnection(_T("Z:"),FALSE);  //取消了Z:現有的網路連線

 WNetAddConnection2()

MSDN原話:The WNetAddConnection2 function makes a connection to a network resource. The function can redirect a local device to the network resource

翻譯過來是:WNetAddConnection2函式連線到網路資源。該函式可以將本地裝置重定向到網路資源

補充:WNetAddConnection2函式取代了WNetAddConnection函式。如果您可以將網路資源的提供者用作對話方塊的所有者視窗,那麼可以將其傳遞給視窗,從而呼叫WNetAddConnection3函式

Syntax

DWORD WNetAddConnection2(
  __in  LPNETRESOURCE lpNetResource,
  __in  LPCTSTR lpPassword,
  __in  LPCTSTR lpUsername,
  __in  DWORD dwFlags
);

Parameters

lpNetResource

A pointer to a NETRESOURCE structure that specifies details of the proposed connection, such as information about the network resource, the local device, and the network resource provider.

You must specify the following members of the NETRESOURCE structure.

一個指向NETRESOURCE結構的指標,它指定了擬議連線的詳細資訊,例如關於網路資源、本地裝置和網路資源提供者的資訊。

//該結構體可以列舉出網路鄰居資訊
//typedef struct  _NETRESOURCEA {
//	DWORD    dwScope; //列舉成員的範圍 1列舉當前連線的資源 2列舉網路上的所有資源 3列舉(持久)連線
//	DWORD    dwType;  //資源的型別  1所有資源 2磁碟資源 3 列印資源
//	DWORD    dwDisplayType;  //網路物件顯示選項 顯示為域、伺服器、共享、檔案、組、網路、網路的邏輯根、adminstrshare共享、目錄、樹、Netware目錄服務容器
//	DWORD    dwUsage;  //描述如何使用資源的一組位標誌 1資源是可連線的資源 2資源是一個容器資源 3資源不是本地裝置 4資源是兄弟姐妹 5必須附加資源
//	LPSTR    lpLocalName; //它指定了本地裝置的名稱。如果連線不使用裝置,該成員為NULL。
//	LPSTR    lpRemoteName; //網路名稱  
//	LPSTR    lpComment ; //該字串包含由網路提供程式提供的註釋。
//	LPSTR    lpProvider; //該字串包含擁有該資源的提供者的名稱。如果提供者名稱未知,該成員可以為NULL
//}NETRESOURCEA, *LPNETRESOURCEA;


您必須指定NETRESOURCE結構的下列成員。

Member Meaning

dwType

The type of network resource to connect to.

If the lpLocalName member points to a nonempty string, this member can be equal to RESOURCETYPE_DISK or RESOURCETYPE_PRINT.

If lpLocalName is NULL, or if it points to an empty string, dwType can be equal to RESOURCETYPE_DISK, RESOURCETYPE_PRINT, or RESOURCETYPE_ANY.

Although this member is required, its information may be ignored by the network service provider.

連線到的網路資源的型別。
如果lpLocalName成員指向非空字串,則該成員可以等於resources pedisk或resources peprint。
如果lpLocalName為NULL,或者如果它指向空字串,dwType就可以等於resources pedisk、resources peprint或resources peany。
儘管這個成員是必需的,但是它的資訊可能會被網路服務提供者忽略。

lpLocalName

A pointer to a null-terminated string that specifies the name of a local device to redirect, such as "F:" or "LPT1". The string is treated in a case-insensitive manner.

If the string is empty, or if lpLocalName is NULL, the function makes a connection to the network resource without redirecting a local device.

一個指向一個空終止字串的指標,它指定要重定向的本地裝置的名稱,如“F:”或“LPT1”。字串以不區分大小寫的方式處理。
如果弦是空的,或者如果lpLocalName是NULL,那麼該函式就會在不重定向本地裝置的情況下連線到網路資源。

lpRemoteName

A pointer to a null-terminated string that specifies the network resource to connect to. The string can be up to MAX_PATH characters in length, and must follow the network provider's naming conventions.

一個指向一個空終止字串的指標,它指定連線到的網路資源。該字串可以長到maxpath字元,並且必須遵循網路提供者的命名約定。

lpProvider

A pointer to a null-terminated string that specifies the network provider to connect to.

If lpProvider is NULL, or if it points to an empty string, the operating system attempts to determine the correct provider by parsing the string pointed to by the lpRemoteName member.

If this member is not NULL, the operating system attempts to make a connection only to the named network provider.

You should set this member only if you know the network provider you want to use. Otherwise, let the operating system determine which provider the network name maps to.

一個指向一個空終止字串的指標,它指定連線到的網路提供者。
如果lpProvider是NULL,或者如果它指向一個空字串,作業系統將嘗試通過解析lpRemoteName成員指向的字串來確定正確的提供者。
如果該成員不是空的,作業系統將嘗試只與具名網路提供者建立連線。
如果您知道您想要使用的網路提供者,您應該只設置這個成員。否則,讓作業系統決定網路名稱對映到哪個提供者。

lpPassword

A pointer to a constant null-terminated string that specifies a password to be used in making the network connection.

If lpPassword is NULL, the function uses the current default password associated with the user specified by the lpUserName parameter.

If lpPassword points to an empty string, the function does not use a password.

If the connection fails because of an invalid password and the CONNECT_INTERACTIVE value is set in the dwFlags parameter, the function displays a dialog box asking the user to type the password.

Windows Me/98/95:  This parameter must be NULL or an empty string.

一個指向一個恆定的空終止字串的指標,該字串指定用於建立網路連線的密碼。
如果lpPassword是空的,該函式使用與lpUserName引數指定的使用者相關聯的當前預設密碼。
如果lpPassword指向一個空字串,則該函式不使用密碼。
如果由於無效密碼而導致連線失敗,並且在dwFlags引數中設定了connectinteractive值,則該函式將顯示一個對話方塊,要求使用者輸入密碼。
Windows me/98/95:該引數必須為NULL或空字串。 

lpUsername

A pointer to a constant null-terminated string that specifies a user name for making the connection.

If lpUserName is NULL, the function uses the default user name. (The user context for the process provides the default user name.)

The lpUserName parameter is specified when users want to connect to a network resource for which they have been assigned a user name or account other than the default user name or account.

The user-name string represents a security context. It may be specific to a network provider.

Windows Me/98/95:  This parameter must be NULL or an empty string.

一個指向一個永久的空終止字串的指標,它指定了一個使用者名稱來進行連線。
如果lpUserName為NULL,則該函式使用預設使用者名稱。(該流程的使用者上下文提供預設使用者名稱。)
當用戶想要連線到一個網路資源時,lpUserName引數是指定的,因為他們被分配了一個使用者名稱或帳戶,而不是預設的使用者名稱或帳戶。
使用者名稱字串表示安全上下文。它可能是特定於網路提供者的。
Windows me/98/95:該引數必須為NULL或空字串。 

dwFlags

A set of connection options. The following values are currently defined.

一組連線選項。下面的值是當前定義的

Value Meaning

CONNECT_INTERACTIVE

If this flag is set, the operating system may interact with the user for authentication purposes.

CONNECT_PROMPT

This flag instructs the system not to use any default settings for user names or passwords without offering the user the opportunity to supply an alternative. This flag is ignored unless CONNECT_INTERACTIVE is also set.

CONNECT_REDIRECT

This flag forces the redirection of a local device when making the connection.

If the lpLocalName member of NETRESOURCE specifies a local device to redirect, this flag has no effect, because the operating system still attempts to redirect the specified device. When the operating system automatically chooses a local device, the dwType member must not be equal to RESOURCETYPE_ANY.

If this flag is not set, a local device is automatically chosen for redirection only if the network requires a local device to be redirected.

Windows Server 2003 and Windows XP:  When the system automatically assigns network drive letters, letters are assigned beginning with Z:, then Y:, and ending with C:. This reduces collision between per-logon drive letters (such as network drive letters) and global drive letters (such as disk drives). Note that earlier versions of Windows assigned drive letters beginning with C: and ending with Z:.

CONNECT_UPDATE_PROFILE

The network resource connection should be remembered.

If this bit flag is set, the operating system automatically attempts to restore the connection when the user logs on.

The operating system remembers only successful connections that redirect local devices. It does not remember connections that are unsuccessful or deviceless connections. (A deviceless connection occurs when the lpLocalName member is NULL or points to an empty string.)

If this bit flag is clear, the operating system does not automatically restore the connection at logon.

CONNECT_COMMANDLINE

If this flag is set, the operating system prompts the user for authentication using the command line instead of a graphical user interface (GUI). This flag is ignored unless CONNECT_INTERACTIVE is also set.

Windows 2000/NT and Windows Me/98/95:  This value is not supported.

CONNECT_CMD_SAVECRED

If this flag is set, and the operating system prompts for a credential, the credential should be saved by the credential manager. If the credential manager is disabled for the caller's logon session, or if the network provider does not support saving credentials, this flag is ignored. This flag is also ignored unless you set the CONNECT_COMMANDLINE flag.

Windows 2000/NT and Windows Me/98/95:  This value is not supported.

Return Value

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is a system error code, such as one of the following values.

如果函式成功,返回值是noerror。
如果函式失敗,退貨值是一個系統錯誤程式碼,比如下列值之一

Return code Description

ERROR_ACCESS_DENIED

The caller does not have access to the network resource.

ERROR_ALREADY_ASSIGNED

The local device specified by the lpLocalName member is already connected to a network resource.

ERROR_BAD_DEV_TYPE

The type of local device and the type of network resource do not match.

ERROR_BAD_DEVICE

The value specified by lpLocalName is invalid.

ERROR_BAD_NET_NAME

The value specified by the lpRemoteName member is not acceptable to any network resource provider, either because the resource name is invalid, or because the named resource cannot be located.

ERROR_BAD_PROFILE

The user profile is in an incorrect format.

ERROR_BAD_PROVIDER

The value specified by the lpProvider member does not match any provider.

ERROR_BUSY

The router or provider is busy, possibly initializing. The caller should retry.

ERROR_CANCELLED

The attempt to make the connection was canceled by the user through a dialog box from one of the network resource providers, or by a called resource.

ERROR_CANNOT_OPEN_PROFILE

The system is unable to open the user profile to process persistent connections.

ERROR_DEVICE_ALREADY_REMEMBERED

An entry for the device specified by lpLocalName is already in the user profile.

ERROR_EXTENDED_ERROR

A network-specific error occurred. Call the WNetGetLastError function to obtain a description of the error.

ERROR_INVALID_PASSWORD

The specified password is invalid and the CONNECT_INTERACTIVE flag is not set.

ERROR_NO_NET_OR_BAD_PATH

The operation cannot be performed because a network component is not started or because a specified name cannot be used.

ERROR_NO_NETWORK

The network is unavailable.

這個函式看著很複雜,其實實際應用起來也不算很難,當然了,我這邊只應用到該函式連線網路共享磁碟的功能

//設定結構體
NETRESOURCE res = {0};
res.dwType = RESOURCETYPE_DISK;
res.lpLocalName = _T("Z:") ;
//res.lpRemoteName = (LPWSTR)szsharepath;
res.lpRemoteName = _T("\\\\192.168.6.75\\VirtualMachine");
res.lpProvider = NULL;

WNetCancelConnection(_T("Z:"),FALSE);//取消了Z:現有的網路連線
DWORD dwRet = WNetAddConnection2(&res,_T("tht124254"),_T("bwda"),CONNECT_REDIRECT); 

程式碼

#include <Windows.h>
#include <iostream>
#include <string>
#include <Shlwapi.h> 
#include <time.h>
#include <fstream> 
#include <process.h>
#include <tchar.h>
#include <WinNetWk.h>


using namespace std;
#pragma comment(lib,"Mpr.lib")
#pragma comment(lib, "shlwapi.lib")

void ConnectRemoteDisk()  //連線遠端磁碟
{
	while(TRUE)
	{
		if(!PathFileExistsA("Z:"))
		{
			printf("本地不存在該共享磁碟\n");
			//開始遠端連線共享磁碟
            DWORD dwusername = 255;
			char szusername[256] = {0};
			GetUserNameA(szusername,&dwusername);
			printf("%s\n",szusername);

			char szsharepath[256] = "\\\\192.168.6.75\\VirtualMachine"; 
            printf("%s\n",szsharepath);
			//strcat(szsharepath,szusername);
			//printf("%s\n",szsharepath);

			//設定結構體
			NETRESOURCE res = {0};
			res.dwType = RESOURCETYPE_DISK; 
			res.lpLocalName = _T("Z:") ;
			//res.lpRemoteName = (LPWSTR)szsharepath;
			res.lpRemoteName = _T("\\\\192.168.6.75\\VirtualMachine");
			res.lpProvider = NULL;

			WNetCancelConnection(_T("Z:"),FALSE);//取消了Z:現有的網路連線
		    DWORD dwRet = 
            WNetAddConnection2(&res,_T("tht124254"),_T("bwda"),CONNECT_REDIRECT); 
            if (NO_ERROR != dwRet)//(4)連線失敗
			{
				printf("連線失敗\n");
				printf("%d",GetLastError());
               // WriteLogFile("遠端連線磁碟失敗\n");
			}
			else
			{
				printf("連線成功\n");
               // WriteLogFile("遠端連線磁碟成功\n");
			}
			break;
		}
		else
		{
			printf("本地存在該共享磁碟\n");
			break;
		}
	}
}

int main()
{
    //const char * szlog = "連線遠端磁碟測試";
   // WriteLogFile(szlog);
    //Get_SetLastError();   //測試setlasterror跟getlasterror兩個函式
    //int Tres = Text_MUTEX();  //測試createmutex 建立互斥體函式
    // Text_threadex();    //測試_beginthreadex函式跟_endthreadex函式
	//Text_PathFileExists(); //測試碟符是否存在
    ConnectRemoteDisk();  //連線遠端磁碟

    system("pause");

	return 0;
}

補充

一般而言想要連線一個內網共享資料夾需要ip地址及資料夾名字

類似下面格式

當你確定後會讓你輸入登入的賬號跟密碼

程式碼中res.lpRemoteName = _T("\\\\192.168.6.75\\VirtualMachine");這句是在結構體 NETRESOURCEA中設定連線的網路資訊

WNetAddConnection2(&res,_T("tht124254"),_T("bwda"),CONNECT_REDIRECT);這函式的引數設定的使用者名稱_T("bwda")跟密碼_T("tht124254")