2009-02-27 4 views
1

C#으로 작성된 사용자 작업 표시 줄에있는 UI 응용 프로그램이 있습니다. 도구에 대한 EXE는이를 사용하는 여러 프로젝트에서 소스 제어 시스템에 체크인되므로 업데이트 된 EXE를 체크인하여 실행 버전을 업데이트 할 수 있습니다.C#의 메모리에서 프로그램을 시작하려면 어떻게해야합니까?

문제는 사용자가 최신 버전의 exe를 다운로드하면 프로그램이 실행되고 컴퓨터에서 동기화가 실패하는 것입니다. 프로그램을 종료하지 않고도 동기화 할 수 있도록 프로그램이 실행될 때 프로그램이 EXE 및 종속 DLL을 잠그지 않도록 수정하려고합니다.

현재 실행 파일을 매개 변수로 사용하고 어셈블리 내용을 메모리로 미리 읽어 메모리에서 시작하는 프로그램이 있습니다. 유감스럽게도, 이것은 프로그램이 요구하는 DLL에 관해서는 완전히 실패합니다.

public class ExecuteFromMemory 
{ 
    public static void Main(string[] args) 
    { 
     //Figure out the name of the EXE to launch and the arguments to forward to it 
     string fileName = args[0]; 
     string[] realArgs = new string[args.Length - 1]; 
     Array.Copy(args, 1, realArgs, 0, args.Length - 1); 

     //Read the assembly from the disk 
     byte[] binary = File.ReadAllBytes(fileName); 

     //Execute the loaded assembly using reflection 
     Assembly memoryAssembly = null; 
     try 
     { 
      memoryAssembly = Assembly.Load(binary); 
     } 
     catch (Exception ex) 
     { 
      //Print error message and exit 
     } 

     MethodInfo method = memoryAssembly.EntryPoint; 
     if (method != null && method.IsStatic) 
     { 
      try 
      { 
       method.Invoke(null, new object[] { realArgs }); 
      } 
      catch(Exception ex) 
      { 
       //Print error message and exit 
      } 
     } 
     else 
     { 
      //Print error message and exit 
     } 
    } 
} 

내 질문에, 나는 완전히 바보 같은 일을하고있다 :

내가 가진 코드는 지금과 같이 보입니다? 이 문제를 해결할 더 좋은 방법이 있습니까? 그렇지 않은 경우, 외부 종속성 처리를 지원하려면 어떻게해야합니까?

예를 들어 'Bar.dll'의 기능을 사용하는 'Foo.exe'를 실행하려고하면 위의 코드가 종속 파일을로드하지 못하고 'Foo.exe'는 덮어 쓸 수 있지만 'Bar'는됩니다. dll '은 여전히 ​​잠겨 있으며 덮어 쓸 수 없습니다.

로드 된 assmebly의 'GetReferencedAssemblies()'메소드에서 참조 된 어셈블리 목록을 가져 오려고했으나 어셈블리를로드해야하는 위치를 알려주지 않는 것으로 보입니다. 검색해야합니까? 그들 자신을 위해서? 그렇다면이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

다른 사람들이 전에이 문제를 경험 한 것 같아서 바퀴를 다시 발명하고 싶지 않습니다.

- 업데이트 : EXE는 우리가 사내 도구를 사용하는 팀에 사내 도구를 배포하는 방식으로 인해 체크 인됩니다. 이 유스 케이스에는 최적이 아니지만 그 정책을 변경할 기회가 없다.

+0

왜 메모리에서 실행 하시겠습니까? 이것은 프로그램을 라이브 바이러스처럼 보이게하는 좋은 방법입니다. – Migol

답변

1

업데이트하는 동안 계속 실행하려면이 필요합니까?

일반적으로 실행중인 프로그램을 업데이트하려면 임시 폴더로 바꿀 파일을 복사하십시오. 그런 다음 이전 인스턴스를 종료하고 삭제 한 다음 새 파일을 올바른 위치로 옮긴 다음 다시 시작하십시오.

이렇게하면 임시 폴더가 동일한 논리 드라이브에있는 경우 가장 긴 부분이 일반적으로 복사되고 파일 이동이 매우 빠르기 때문에 응용 프로그램의 다운 시간을 최소화 할 수 있습니다.

4

면책 조항 : 나는 물건을 고정시키는 이상한 방법에 익숙하지만 Windows는 사용하지 않습니다.

실행중인 응용 프로그램을 업데이트하려면 실행 프로세스 자체와 업데이트 프로세스를 완료 할 수있는 업데이트 "도우미"응용 프로그램의 두 가지 프로세스가 필요할 수 있습니다. 응용 프로그램이 ProcessA.exe이고 업데이트 도우미가 Updater.exe라고 가정 해 봅시다. 주 프로그램은 실행 파일의 새 복사본을 다운로드하여 임의의 이름으로 저장합니다. 그런 다음 현재 프로세스의 종료를 감시하는 업데이터 프로그램을 실행합니다. 프로세스가 종료되면 업데이트 상태를 보여주는 빠른 창과 새 실행 파일을 이전 위치로 이동 한 다음 해당 프로그램을 다시 시작하는 창을 표시합니다.

POSIX 파일 시스템 의미론을 에뮬레이트하고 현재 실행중인 프로세스 디스크 이미지를 삭제하고 새 파일로 바꿀 수 있다면 더 좋겠지 만 그게 가능한지 모르겠습니다. Windows. POSIX 시스템에서는 사용중인 파일을 삭제할 수 있으며 남은 파일 핸들이 닫힐 때까지 실제로 삭제되지는 않습니다.하지만 파일 이름을 다시 사용할 수는 있습니다.

CodeProject에 작성된 기사를 확인 하시려면 talks about this입니다. follow-up article도 있습니다.

행운을 빈다.

0

마이클의 대답은이 작업을 수행하는 한 가지 방법이지만 데스크톱에 설치된 것을 관리하기위한 도구가 명시 적으로 있습니다.

exe가 소스 제어에 체크인되고있는 이유는 정상적인 현상이 아닙니다. Windows 도메인 컨트롤러가있는 경우 그룹 정책을 사용하여 프로그램을 클라이언트에 푸시 다운 할 수 있습니다. 또는 Altiris와 같은 것을 사용하여이를 처리 할 수 ​​있습니다.

길을 계속해야한다면 다음 두 가지 옵션이 있습니다. 하나는 실행시 버전 확인을 수행하는 헬퍼/로더 앱을 사용합니다. 이것은 firefox가 작동하는 것과 유사합니다.

두 번째 방법은 메모리에 앉아 업데이트를 위해 자주 폴링하는 도우미 서비스를 만드는 것입니다. 이것은 Google 크롬, Adobe 등이 작동하는 방식입니다.