Скопируйте файл на удаленный компьютер с помощью скрипта C # и NAnt (указанный сеанс входа не существует) - PullRequest
0 голосов
/ 10 июня 2011

В настоящее время я работаю над сценарием (использующим NAnt и C #), работающим на сервере TeamCity, который предназначен для создания и развертывания файла MSI на удаленном компьютере.На удаленном компьютере установлена ​​общая папка, к которой сервер TeamCity должен подключиться и скопировать MSI-файл через скрипт.И он работает в первый раз, когда я запускаю его без проблем.

Но когда я запускаю сценарий второй раз, он выдает исключение со следующим сообщением при попытке подключения к общему ресурсу на удаленном компьютере.;

"A specified logon session does not exist. It may already have been terminated."

Я использую решение из этого потока для копирования файла MSI с сервера TeamCity на удаленный компьютер с использованием учетных данных для входа в систему.

Ниже приведен сценарий C # в моем файле NAnt, который выполняет копирование файла:

//Script main entry point
public static void ScriptMain(Project project)
{
    NetworkCredential deployTargetCridentials = new NetworkCredential(project.Properties["deploy.remotesvr.username"],
                                                                        project.Properties["deploy.remotesvr.password"]);

    string connection = @"\\" + project.Properties["deploy.remotesvr"] + project.Properties["deploy.remotesvr.sharepath"];

    string sourceFile = project.Properties["wix.output.dir"] + @"\" + project.Properties["wix.output.file"] + ".msi";
    string destinationFile = @"\\" + project.Properties["deploy.remotesvr"] +
                                        project.Properties["deploy.remotesvr.sharepath"] + @"\" +
                                        project.Properties["deploy.remotesvr.deployfile"];

    //Copy installation file to deploy share
    Copy(project
            , project.Properties["wix.output.dir"]
            , project.Properties["wix.output.file"] + ".msi"
            , @"\\" + project.Properties["deploy.remotesvr"] + project.Properties["deploy.remotesvr.sharepath"]
            , project.Properties["deploy.remotesvr.deployfile"]
            , deployTargetCridentials);

    ////
}


//Copy MSI
public static void Copy(Project project, string sourcePath, string sourceFile, string destinationPath, string destinationFile, NetworkCredential cridentials)
{
    string source = sourcePath + @"\" + sourceFile;
    string destination = destinationPath + @"\" + destinationFile;

    try
    {
        project.Log(Level.Info, " ");
        project.Log(Level.Info, "Copying " + source + " to " + destination);

        project.Log(Level.Info, "  Connecting to copy share: " + destinationPath);
        using (new NetworkConnection(destinationPath, cridentials))
        {
            project.Log(Level.Info, "  Copying file");
            File.Copy(source, destination, true);
        }
        project.Log(Level.Info, "Copy successfull!");
    }
    catch (Exception ex)
    {
        project.Log(Level.Warning, "WARNING: Could not copy file: " + ex.Message.ToString().Trim().Replace("\r\n", ""));
    }
}


////


//NetworkConnection class
public class NetworkConnection : IDisposable
{
    string _networkName;

    public NetworkConnection(string networkName, NetworkCredential credentials)
    {
        _networkName = networkName;

        NetResource netResource = new NetResource();
        netResource.Scope = ResourceScope.GlobalNetwork;
        netResource.ResourceType = ResourceType.Disk;
        netResource.DisplayType = ResourceDisplaytype.Share;
        netResource.RemoteName = networkName;

        int result = WNetAddConnection2(netResource, credentials.Password, credentials.UserName, 0);

        if (result != 0 && result != 1219)
        {
            throw new Win32Exception(result);
        }
    }

    ~NetworkConnection()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        WNetCancelConnection2(_networkName, 0, true);
    }

    [DllImport("mpr.dll")]
    private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags);

    [DllImport("mpr.dll")]
    private static extern int WNetCancelConnection2(string name, int flags, bool force);
}


[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
    public ResourceScope Scope;
    public ResourceType ResourceType;
    public ResourceDisplaytype DisplayType;
    public int Usage;
    public string LocalName;
    public string RemoteName;
    public string Comment;
    public string Provider;
}

public enum ResourceScope : int
{
    Connected = 1,
    GlobalNetwork,
    Remembered,
    Recent,
    Context
};

public enum ResourceType : int
{
    Any = 0,
    Disk = 1,
    Print = 2,
    Reserved = 8
}

public enum ResourceDisplaytype : int
{
    Generic = 0x0,
    Domain = 0x01,
    Server = 0x02,
    Share = 0x03,
    File = 0x04,
    Group = 0x05,
    Network = 0x06,
    Root = 0x07,
    Shareadmin = 0x08,
    Directory = 0x09,
    Tree = 0x0a,
    Ndscontainer = 0x0b
}

Исключение происходит в следующей строке при копировании;

using (new NetworkConnection(destinationPath, cridentials))

Когда я пыталсязапустить один и тот же код копирования в тестовом приложении, он копирует файл каждый раз.Исключение возникает только тогда, когда я запускаю его через скрипт.

Кто-нибудь знает, почему это так?

1 Ответ

0 голосов
/ 13 июня 2011

Вы пробовали тестировать / закрывать какие-либо существующие соединения перед открытием нового?

...