2011-06-10 2 views
0

현재 MSI를 작성 및 배포하는 TeamCity 서버에서 실행되는 스크립트 (NAnt 및 C# 사용)에서 작업 중입니다. 원격 컴퓨터의 파일. 원격 컴퓨터는 TeamCity 서버가 연결되어 있고 스크립트를 통해 MSI 파일을 복사하는 공유 폴더로 설정됩니다. 그리고 문제없이 처음 실행합니다.C# 스크립트 및 NAnt (지정된 로그온 세션이 존재하지 않음)를 사용하여 원격 컴퓨터에 파일 복사

하지만 스크립트를 두 번 실행하면 원격 컴퓨터의 공유에 연결하려고 할 때 다음 메시지와 함께 예외가 발생합니다.

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

나는 로그온 cridentials를 사용하여 원격 컴퓨터에 인 TeamCity 서버에서 MSI 파일을 복사 할 this 스레드에서 솔루션을 사용합니다. 다음

는 파일 복사 작업을 수행 나의은 NAnt 파일은 C# 스크립트입니다 :

//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)) 

테스트 응용 프로그램에서 동일한 복사 코드를 실행하려고 시도 할 때마다 파일이 복사되었습니다. 예외가 발생하는 스크립트를 통해서만 실행됩니다.

이유에 대한 의견이 있으십니까?

+0

'0'대신'CONNECT_UPDATE_PROFILE'을 시도 했습니까? http://msdn.microsoft.com/en-us/library/aa385427(v=vs.85).aspx –

답변

0

새로운 연결을 열기 전에 기존 연결을 테스트하거나 닫으려고 했습니까?

+0

SO에서 주석 기능을 사용해 보셨습니까? – manojlds

+0

NetworkConnection의 Dispose에서 WNetCancelConnection2에 대한 호출을 제거하려고했는데 아무 문제없이 작동했습니다. 따라서 연결을 취소하면 "지정된 로그온 세션이 존재하지 않습니다. 이미 종료되었을 수 있습니다."라는 메시지가 나타납니다. 같은 컴퓨터에 대한 연결을 두 번 열려고하면 오류가 발생합니다. 나는 왜 지금 그 순간을 볼 수 없는가 .. – Avilan

관련 문제