简体   繁体   English

如何使用C#中的File.Copy将文件从PC复制到服务器

[英]How to copy file from PC to Server using File.Copy in C#

I'm trying to copy an image file from one machine to another machine, but I'm getting an error that the username and password are incorrect. 我正在尝试将图像文件从一台计算机复制到另一台计算机,但是出现错误,提示用户名和密码不正确。

I've put my code below: 我将代码放在下面:

[System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);


    private void Button_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.InitialDirectory = "c:\\";
            dlg.Filter = "Image files (*.jpg)|*.jpg|All Files (*.*)|*.*";
            dlg.RestoreDirectory = true;

            if (dlg.ShowDialog() == true)
            {
                string filepath = dlg.FileName;
                // File.Copy(filepath, @"\\172.18.2.33\c$\Mediinfotec" + dlg.SafeFileName, true);

                IntPtr tokenHandle = new IntPtr(0);
                tokenHandle = IntPtr.Zero;

                bool returnValue = LogonUser(@"prime\mediinfo", "prime", "medi@111", 9, 0, ref tokenHandle);

                AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.UnauthenticatedPrincipal);
                WindowsIdentity wid = new WindowsIdentity(tokenHandle);
                WindowsImpersonationContext context = wid.Impersonate();

                File.Copy(filepath, @"\\172.18.2.33\c$\Mediinfotec\" + dlg.SafeFileName);

                context.Undo();
            }
        }
        catch (Exception ex)
        {

            throw;
        }

    }

Assuming that your server requires you to connect with a username and password, you can use WNetUseConnection from mpr.dll to establish the connection, then WNetCancelConnection to disconnect when you're done. 假设您的服务器要求您使用用户名和密码进行连接,则可以使用WNetUseConnectionmpr.dll建立连接,然后使用WNetCancelConnection断开连接。

I have used this in the past to connect to SMB shares for data collection and so on and it works fine: 我过去曾使用此连接到SMB共享进行数据收集等,并且工作正常:

using System;
using System.Runtime.InteropServices;

namespace Util
{
    public class ConnectSMB : IDisposable
    {
        public string URI { get; private set; }
        public bool Connected { get; private set; } = false;

        public ConnectSMB(string uri, string username, string password)
        {
            string connResult = Native.ConnectToRemote(uri, username, password);

            if (connResult != null)
            {
                URI = $"FAILED: {connResult}";
                Connected = false;
            }
            else
            {
                URI = uri;
                Connected = true;
            }
        }

        public void Dispose()
        {
            Close();
        }

        public void Close()
        {
            if (Connected)
            {
                var disconResult = Native.DisconnectRemote(URI);
                URI = disconResult;
                Connected = false;
            }
        }

        public class Native
        {
            #region Consts
            const int RESOURCETYPE_DISK = 1;
            const int CONNECT_UPDATE_PROFILE = 0x00000001;
            #endregion

            #region Errors
            public enum ENetUseError
            {
                NoError = 0,
                AccessDenied = 5,
                AlreadyAssigned = 85,
                BadDevice = 1200,
                BadNetName = 67,
                BadProvider = 1204,
                Cancelled = 1223,
                ExtendedError = 1208,
                InvalidAddress = 487,
                InvalidParameter = 87,
                InvalidPassword = 1216,
                MoreData = 234,
                NoMoreItems = 259,
                NoNetOrBadPath = 1203,
                NoNetwork = 1222,
                BadProfile = 1206,
                CannotOpenProfile = 1205,
                DeviceInUse = 2404,
                NotConnected = 2250,
                OpenFiles = 2401
            }
            #endregion

            #region API methods
            [DllImport("Mpr.dll")]
            private static extern ENetUseError WNetUseConnection(
                IntPtr hwndOwner,
                NETRESOURCE lpNetResource,
                string lpPassword,
                string lpUserID,
                int dwFlags,
                string lpAccessName,
                string lpBufferSize,
                string lpResult
            );

            [DllImport("Mpr.dll")]
            private static extern ENetUseError WNetCancelConnection2(
                string lpName,
                int dwFlags,
                bool fForce
            );

            [StructLayout(LayoutKind.Sequential)]
            private class NETRESOURCE
            {
                public int dwScope = 0;
                // Resource Type - disk or printer
                public int dwType = RESOURCETYPE_DISK;
                public int dwDisplayType = 0;
                public int dwUsage = 0;
                // Local Name - name of local device (optional, not used here)
                public string lpLocalName = "";
                // Remote Name - full path to remote share
                public string lpRemoteName = "";
                public string lpComment = "";
                public string lpProvider = "";
            }
            #endregion

            public static string ConnectToRemote(string remoteUNC, string username, string password)
            {
                NETRESOURCE nr = new NETRESOURCE { lpRemoteName = remoteUNC };
                ENetUseError ret = WNetUseConnection(IntPtr.Zero, nr, password, username, 0, null, null, null);
                return ret == ENetUseError.NoError ? null : ret.ToString();
            }

            public static string DisconnectRemote(string remoteUNC)
            {
                ENetUseError ret = WNetCancelConnection2(remoteUNC, CONNECT_UPDATE_PROFILE, false);
                if (ret == ENetUseError.NoError) return null;
                return ret == ENetUseError.NoError ? null : ret.ToString();
            }
        }
    }
}

Generally I wrap that in a disposable class that tests for direct access first. 通常,我将其包装在一次性类中,该类首先测试直接访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM