2012-06-18 1 views
2

내 WPF 프로그램에서 사용되는 범용 유틸리티 DLL 파일이 있습니다. 내 프로그램이하는 첫 번째 일은 업데이트 된 dll 파일을 확인하고 dll의 메소드 나 속성을 참조하지 않고 실행중인 디렉토리에 복사합니다.Visual Studio에서 EXE 파일과 DLL로드 시간이 다른 경우

Visual Studio (v10)에서 프로그램을 컴파일하고 실행하면 모든 것이 예상대로 작동합니다. 프로그램이 시작되고 dll 파일을 검사하고 필요한 경우 복사 한 다음 어셈블리 사용을 계속합니다.

Windows 탐색기에서 컴파일 된 .exe 파일을 실행하면 가장 먼저 Util.dll 어셈블리를로드하는 것 같습니다. 이렇게하면 파일이 잠기므로 파일을 업데이트 할 수 없습니다.

누구나 프로그램이 Visual Studio에서 .exe 파일과 다른 이유는 무엇인지에 대한 통찰력이 있습니까? .exe 파일을 실행할 때 어셈블리가로드되는 원인을 추적하는 방법에 대한 의견이 있으십니까? 파일이 복사되는

void AppLoad(object sender, StartupEventArgs e) 
{ 

    //Used to see what assemblies are loaded. 
    System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
    foreach (var item in AppDomain.CurrentDomain.GetAssemblies()) 
    { 
    sb.AppendLine(item.FullName.ToString()); 
    } 
    System.IO.File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "test.txt", sb.ToString()); 


    //Check for the latest Util dll. 
    if (!UpdateUtil()) 
    { 
    //Shutdown. 
    Application.Current.Shutdown(); 
    return; 
    } 

    //Start the main window. 
    MainWindow m = new MainWindow(); 
    m.Show(); 
} 

bool UpdateUtil() 
{ 
    //Verify network path. 
    if (!Directory.Exists(_componentPath)) 
    { 
    MessageBox.Show("The program encountered an error.\r\rPlease contact your Program Administrator with the following information:\r\r" + 
     "Program Name - Genesis Admin\r\r" + 
     "Error Message - Network Component path not found.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
    return false; 
    } 
    //Verify file existance. 
    string sourceFileName = _componentPath + "Util.dll"; 
    if (!File.Exists(sourceFileName)) 
    { 
    MessageBox.Show("The program encountered an error.\r\rPlease contact your Program Administrator with the following information:\r\r" + 
     "Program Name - Genesis Admin\r\r" + 
     "Error Message - Network Util file not found.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
    return false; 
    } 

    string destFileName = AppDomain.CurrentDomain.BaseDirectory + "Util.dll"; 
    if (!File.Exists(destFileName) || File.GetLastWriteTime(sourceFileName) > File.GetLastWriteTime(destFileName)) 
    File.Copy(sourceFileName, destFileName, true); 

    return true; 
} 
+1

FYI 이것은 대부분의 IT 관리자가이 방법을 사용하지 않을 경우 (매우 안전하지 않음) 실제 프로덕션 환경에서는 작동하지 않습니다. – tsells

답변

6

일반적으로 위험한 일입니다. 어셈블리는 메서드의 컴퓨터 코드를 생성해야 할 때 Just-In-Time 컴파일러에서로드합니다. 아마 당신이 기대하지 않는 것은 인라인을 얻는 코드입니다.이 최적화는 릴리즈 빌드에서 사용 가능합니다. 디버거를 사용하여 실행하면이 최적화는 에서입니다.

스 니펫에서 "util.dll"에서로드 할 수있는 유형이 명확하지 않습니다. 그러나 모두 util.dll의 형식이 UpdateUtil() 호출에서 멀리 떨어진 별도의 메서드에 있도록 코드를 구조 조정해야합니다. 메서드의 [MethodImpl (MethodImplOptions.NoInlining)] 특성을 사용하여 인라인을 표시하지 않습니다.

테스트를 수행하는 작은 부트 스트 래퍼 .exe 파일을 사용하는 것이 가장 좋은 방법입니다. 그런 다음 주 .exe를 시작합니다. 그러나 사용자의 컴퓨터에서이 코드를 실행할 때 의심의 여지가 없다는 것을 명심하십시오. DLL을 UAC 권한 상승없이 c : \ program 파일에 복사 할 수 없습니다. 이것은 실제로 설치 프로그램 작업이며 코드에 있어서는 안됩니다.

+0

Util.dll이 MainWindow 클래스에서 사용되었습니다. 그 이유는 앱로드에서 확인/업데이트 중이었기 때문입니다. 내가 볼 수있는 문제는 컴파일이 릴리즈 빌드로 설정되었을 때입니다. 그 과정이 이상적이지는 않다는 것을 알지만, 나는 그 일을 더 잘 할 수있는 경험이 부족합니다. 이것은 내가 일하는 작은 회사를위한 것이며 제한된 사용자 기반을 가질 것입니다. –

+0

음, MainWindow를 사용하는 마지막 두 줄을 별도의 메서드로 이동하고 [MethodImpl] 특성을 지정하십시오. –

+0

인라인 최적화가 문제였습니다. 도와 주셔서 감사합니다. –

1

확인 : 여기

는 프로그램 시작의 코드입니다. 내가 틀릴 수도 있지만 Visual Studio에서 현재 폴더로 프로젝트의 폴더를 사용할 수 있으며, 탐색기에서 시작하면 실행 파일의 위치가 작업 디렉토리로 사용됩니다.

destFileName 값을 출력 할 수 있습니까 (예 : 메시지 상자 사용). 나는 dot net의 전문가는 아니지만 일반적으로 일반 DLL에는 지연된로드를 사용합니다. this page에 유용한 정보가있을 수 있습니다. 그러나 다시 한번 나는 망점을 모른다.

+0

나는 항상 올바른 위치로 복사한다는 것을 알고 있으므로 app 기본 디렉토리를 사용합니다. 생각해 줘서 고마워. –

0

업데이트 된 파일을 찾아야하는 경우 기본 프레임 워크의 플러그를 사용할 수 있습니다. 개념은 디렉토리의 특정 이름으로 모든 파일을 찾은 다음 프로그램에로드하는 것입니다. 프로그램을 시작하자마자 인터페이스를 사용하여 컴파일되지 않도록하십시오.

관련 문제