4

FileVersionInfo.GetVersionInfo()를 사용하여 좀 괴괴 망측하게되어 누군가가 도움을 줄 수 있기를 바랍니다.콘솔 응용 프로그램에서 FileVersionInfo.GetVersionInfo()가 올바르지 않습니다.

문제의 기본은 GetVersionInfo()를 호출하는 폴더의 모든 파일을 반복하는 것입니다. 약 300 개의 파일이 있습니다. 이것은 파일 2 개를 제외한 모든 파일에서 정상적으로 작동합니다. 이 DLL들에 대해서는 GetVersionInfo()에서 잘못된 정보를 얻고 있습니다.

다른 변수를 모두 없애기 위해이 호출을 간단한 테스트 응용 프로그램으로 추출했지만 여전히 동일한 문제가 있습니다. 그러나 테스트 응용 프로그램을 Windows 응용 프로그램 (초기에 콘솔 응용 프로그램)으로 만든 경우 데이터가 올바르게 반환되었습니다.

콘솔 앱으로 실행할 때 돌아 오는 잘못된 데이터는 파일에 버전 데이터가없는 경우 얻을 수있는 null 정보가 아닙니다. 합리적인 데이터가 포함되었지만 잘못된 데이터 만 포함되었습니다. 마치 다른 파일에서 읽는 것입니다. 일치하는 버전 데이터가있는 파일을 찾았지만 찾을 수 없습니다.

Windows 응용 프로그램이 아닌 콘솔 응용 프로그램으로 빌드 된 경우이 간단한 호출이 다르게 작동하는 이유는 무엇입니까?

누구나 도움을받을 수 있다면 매우 감사 할 것입니다. , 앤디

RGDS - 코드 추가

using System; 
using System.Diagnostics; 

namespace test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string file = "C:\\ProblemFile.dll"; 
      FileVersionInfo version = FileVersionInfo.GetVersionInfo(file); 
      string fileName = version.FileName; 
      string fileVersion = version.FileVersion; 

      Console.WriteLine(string.Format("{0} : {1}", fileName, fileVersion)); 
     } 
    } 
} 
+0

문제를 나타내는 코드를 게시하는 방법에 대해 ... –

+0

감사합니다. 미치가 추가되었습니다. 보시다시피, 특별한 일은하지 않습니다. 콘솔 응용 프로그램 또는 Windows 응용 프로그램으로 빌드 할 때 다른 결과가 나타납니다. (분명히 Windows 응용 프로그램으로 Console.WriteLine 작동하지 않지만 중단 점을 사용하여 결과를 볼 수 있습니다.) 난 단지 몇 가지 DLL에서 문제가 발생, 다른 모든 잘 작동합니다. DLL에 관해 특별한 것은 모르지만 회사의 다른 팀의 결과물입니다. VS2005/.NET 2.0을 사용하면 도움이됩니다. – Andy

+0

참고 : ** 저는 VS2005/.NET 2.0을 사용하고 있습니다 **. 문제 DLL은 VS6.0입니다. C++ – Andy

답변

8

이 동작은 실제로 이상하게 보입니다. 콘솔 응용 프로그램이 WinForms 응용 프로그램과 동일한 위치에서 DLL을로드하지 않을 수 있습니까? 이것은 GetVersionInfo이 Win32 CreateFile이 아닌 다른 API를 사용한다는 것을 의미합니다 (일부 DLL 확인자 메커니즘을 통해 진행될 수도 있습니다). 해당 커버 아래에 version.dll이 CLR이 아닌 요청을 실행한다는 것을 기억하십시오.

는 또 다른 방향으로 FileVersionInfo Reflector을 통해 지점에서 상대 : 당신이 볼 수 있듯이

public static unsafe FileVersionInfo GetVersionInfo(string fileName) 
{ 
    // ... 
    int fileVersionInfoSize = UnsafeNativeMethods.GetFileVersionInfoSize(fileName, out num); 
    FileVersionInfo info = new FileVersionInfo(fileName); 
    if (fileVersionInfoSize != 0) 
    { 
     byte[] buffer = new byte[fileVersionInfoSize]; 
     fixed (byte* numRef = buffer) 
     { 
      IntPtr handle = new IntPtr((void*) numRef); 
      if (!UnsafeNativeMethods.GetFileVersionInfo(fileName, 0, fileVersionInfoSize, new HandleRef(null, handle))) 
      { 
       return info; 
      } 
      int varEntry = GetVarEntry(handle); 
      if (!info.GetVersionInfoForCodePage(handle, ConvertTo8DigitHex(varEntry))) 
      { 
       int[] numArray = new int[] { 0x40904b0, 0x40904e4, 0x4090000 }; 
       foreach (int num4 in numArray) 
       { 
        if ((num4 != varEntry) && info.GetVersionInfoForCodePage(handle, ConvertTo8DigitHex(num4))) 
        { 
         return info; 
        } 
       } 
      } 
     } 
    } 
    return info; 
} 

는, 몇 가지 흥미로운 춤은 코드 페이지로 진행된다. 검사 한 DLL에 여러 버전 정보 리소스가 첨부되어 있다면 어떻게 될까요? GetVersionInfo으로 전화하는 프로그램의 문화권에 따라 코드 페이지 관련 호출이 다른 결과를 반환 할 수 있다고 생각합니까?

DLL의 리소스를 확인하고 버전 정보에 대한 언어/코드 페이지가 하나만 있는지 확인하십시오. 해결책을 제시 할 수도 있습니다.

+0

감사합니다. Pierre, 분명히 여기에 뭔가있는 것 같습니다. 문제의 DLL에는 두 개의 버전 리소스가 있는데 하나는 en-GB이고 다른 하나는 en-US입니다. 미국 버전의 올바른 데이터가 있습니다. 내 문화권을 en-US로 변경하면 콘솔 앱이 en-US 버전을 선택하게됩니다. 그러나 Windows App은 내 문화가 en-GB 인 경우에도 en-US 버전을 선택합니다. 왜 이런 일이 일어날 지 아십니까? – Andy

+0

안녕하세요, Andy. 나는 그것이 유용하다고 생각한다면 대답을 위해 upvote 버튼을 클릭 할 것을 제안 할 것이다. 이것이 StackOverflow가 작동하는 방식입니다 ;-). 아니, 아, 문화가 어떻게 파생되는지 전혀 모르겠습니다. 당신은'System.Threading.Thread.CurrentThread.CurrentCulture'에 접근하여 콘솔과 WinForms 애플 리케이션 사이의 결과를 비교해 볼 수 있습니다. –

+0

지금 해 보았습니다. 전에 충분한 담당자가 없었어요! CurrentCulture 및 CurrentUICulture를 살펴본 결과 콘솔과 Windows에서 모두 동일합니다 (각각 en-GB, ko-US). 둘 다 en-US로 변경하면 Console App이 변경되지만 Windows App은 변경되지 않습니다. 여전히 질문을 남기고 있지만이 두 DLL을 사용할 수있을만큼 충분한 시간을줍니다. 당신의 도움을 주셔서 감사합니다. – Andy

0

확인 "파일이"당신이보고있는이 없습니다. 그리고 ..? 모든 파일을 반복 할 경우에 대한 항목이 항상 표시됩니다. (현재 dir) 및 .. (dir). GetVersion Info는 이것들을 위해 무엇이든 반환 할 것입니다. 이 항목을 수동으로 이름별로 필터링해야합니다.

+0

감사합니다. Bob,하지만 그렇습니다. 내가 언급 한 테스트 응용 프로그램에서 파일 이름을 하드 코딩했으며 문제 파일 중 하나에서 GetVersion()을 한 번 호출했습니다. – Andy

0

파일 및 어셈블리 버전은 2 가지입니다.

다른 것을 기대하지 않으시겠습니까?

+0

조립품 버전이 확실하지 않습니다. FileVersionInfo를 볼 때 FileVersion 및 ProductVersion을 볼 수 있습니다. 콘솔 앱으로 빌드 할 때 이들은 모두 "1, 0, 0, 1"입니다. Windows 응용 프로그램으로 빌드 할 때 "4, 2, 004, 6102"입니다. Windows 탐색기에서 등록 정보를 가져 와서 버전 탭을 보면 다른 버전 정보 인 파일 버전과 제품 버전이 모두 "4, 2, 004, 6102"로 표시됩니다. – Andy

+0

'AssemblyInfo.cs'에서 적용하는 2 가지 다른 속성이 있습니다. 아마도 서로 다릅니다. 그게 내가 생각할 수있는 전부 야. – leppie

+0

아, 내 프로젝트에서 볼 수 있지만 문제가 DLL에 대한 속성 창에 표시되지 않습니다. 이들은 .NET DLL이 아니며, VS6.0 C++이라고 생각합니다. – Andy

0

업데이트 : 시도해 보았습니다. 일하지 않았어.

using System; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 

namespace test 
{ 
    class Program 
    { 
     [DllImport("COMCTL32")] 
     private static extern int InitCommonControls(int nExitCode); 

     static void Main(string[] args) 
     { 
      InitCommonControls(0); 

      string file = "C:\\ProblemFile.dll"; 
      FileVersionInfo version = FileVersionInfo.GetVersionInfo(file); 
      string fileName = version.FileName; 
      string fileVersion = version.FileVersion; 

      Console.WriteLine(string.Format("{0} : {1}", fileName, fileVersion)); 
     } 
    } 
}