C# winforms 程序:需要将文件复制到另一台 windows PC

C# winforms program: need to copy files onto another windows PC

我正在尝试编写一个可以将一些文件复制到另一台 windows PC 上的 c# winform 程序。两台电脑都是 运行 Windows 7 但目的地没有共享文件夹。 我没问题 运行 scp 将文件复制到 Linux 框,但是 Windows 中没有 SSH 服务器在等我:-( 我将获得远程 PC 的登录详细信息(IP 地址、用户名和密码),但我不熟悉在 Windows 环境中通常如何完成此操作。 该程序的目的是自动将一些更新文件部署到多台机器上。我们将无法使用 windows 共享来传输这些文件,因为这并不比手动登录并通过 vnc 复制文件快。

在 Internet 上做了一些研究并针对 Windows XP 机器进行了实验(这是我碰巧拥有本地管理员帐户的唯一一台机器 - 希望它能在 Windows 7机)。

最终我意识到远程共享是正确的前进方向 - 感谢那些发表评论的人:-)

请注意,在示例代码中,我使用了一个名为 mDisplay 的 class 实例 - 它用于为我处理显示内容,例如显示错误消息或结果,而不是当前问题的核心。

第一个问题——如何在没有人工干预的情况下在远程机器上创建共享。

public bool CreateShare(string ipAddress, string username, string password, string remoteFolder, string sharename)
{
    bool result = false;

    try
    {
        // Create management scope and connect to the remote machine
        ConnectionOptions options = new ConnectionOptions();
        options.Username = username;
        options.Password = password;
        string path = string.Format(@"\{0}\root\cimv2", ipAddress);
        ManagementScope scope = new ManagementScope(path, options);
        scope.Connect();

        // http://www.c-sharpcorner.com/forums/creating-a-remote-share-using-wmi-in-c-sharp
        ManagementPath winSharePath = new ManagementPath("Win32_Share");
        ManagementClass winShareClass = new ManagementClass(scope, winSharePath, null);
        ManagementBaseObject shareParams = winShareClass.GetMethodParameters("Create");
        shareParams["Path"] = remoteFolder;
        shareParams["Name"] = sharename;
        shareParams["Type"] = 0;
        shareParams["Description"] = "Temporary folder share";
        ManagementBaseObject winShareResult = winShareClass.InvokeMethod("Create", shareParams, null);

        result = true;
    }
    catch (Exception ex)
    {
        mDisplay.showError("FAILED to create share: " + ex.Message.ToString());
    }

    return result;
}

第二个问题 - 将文件从本地机器复制到远程机器

感谢 How to create a recursive function to copy all files and folders 作为此代码的基础。 我的版本不一定是完成这项工作的最有效或最紧凑的方式,但它对我有用。

public bool CopyFiles(bool overwrite, string ipAddress, string sharename, string copySource)
{
    bool result = false;

    string path = string.Format(@"\{0}\{1}", ipAddress, sharename);

    if (!Directory.Exists(path))
    {
        mDisplay.appendToResults("Share doesn't exist \"" + path + "\" - are you sure it mapped ok?");
        return result;
    }

    if (!Directory.Exists(copySource))
    {
        mDisplay.appendToResults("Source folder \"" + copySource + "\" doesn't exist, need to specify where to copy file(s) from");
        return result;
    }

    recursivelyCopyContents(copySource, overwrite, path);
    result = true;

    return result;
}
private void recursivelyCopyContents(string sourceDirName, bool overwrite, string destDirName)
{
    try
    {
        // Get the subdirectories for the specified directory.
        DirectoryInfo dir = new DirectoryInfo(sourceDirName);

        if (!dir.Exists)
        {
            throw new DirectoryNotFoundException(
                "Source directory does not exist or could not be found: "
                + sourceDirName);
        }

        DirectoryInfo[] dirs = dir.GetDirectories();
        // If the destination directory doesn't exist, create it.
        if (!Directory.Exists(destDirName))
        {
            mDisplay.appendToResults("Creating folder " + destDirName);
            Directory.CreateDirectory(destDirName);
        }

        // Get the files in the directory and copy them to the new location.
        FileInfo[] files = dir.GetFiles();
        foreach (FileInfo file in files)
        {
            string temppath = Path.Combine(destDirName, file.Name);

            string info = "Copying " + file.Name + " -> " + temppath;


            if (!overwrite && File.Exists(temppath))
            {
                // Not overwriting - so show it already exists
                mDisplay.appendToResults(info + " (already exists)");
            }
            else
            {
                file.CopyTo(temppath, overwrite);
                mDisplay.appendToResults(info + " OK");
            }
        }

        foreach (DirectoryInfo subdir in dirs)
        {
            string temppath = Path.Combine(destDirName, subdir.Name);
            recursivelyCopyContents(subdir.FullName, overwrite, temppath);
        }
    }
    catch (Exception ex)
    {
        mDisplay.showError("Problem encountered during copy : " + ex.Message);
    }
}

最后 - 删除我之前创建的远程共享,不希望它留在远程机器上。

public bool RemoveShare(string username, string password, string ipAddress, string sharename)
{
    bool result = false;

    try
    {
        // Create management scope and connect to the remote machine
        ConnectionOptions options = new ConnectionOptions();
        options.Username = username;
        options.Password = password;
        string path = string.Format(@"\{0}\root\cimv2", ipAddress);
        ManagementScope scope = new ManagementScope(path, options);
        scope.Connect();

        // Inspiration from here: https://danv74.wordpress.com/2011/01/11/list-network-shares-in-c-using-wmi/
        var query = new ObjectQuery(string.Format("select * from win32_share where Name=\"{0}\"", sharename));
        var finder = new ManagementObjectSearcher(scope, query);
        var shares = finder.Get();

        foreach (ManagementObject share in shares)
        {
            share.Delete();
        }

        mDisplay.appendToResults("Share deleted");
        result = true;
    }
    catch (Exception ex)
    {
        mDisplay.showError("FAILED to remove share: " + ex.Message.ToString());
    }

    return result;
}