2012-03-19 2 views
1

나는 그것을 실행할 때마다 기본적으로 관리자 권한을 요청하는 .net 프로그램을 가지고있다. 특정 상황에서 이러한 권한이 필요한 이유가 무엇인지 모르겠으므로 그 뒤에 게으른 프로그래밍이 의심됩니다 (결국 관리자 권한이 필요할 수도 있음).관리자 권한없이 프로그램을 강제 실행 하시겠습니까?

일반 액세스 권한으로 승격 및 실행하지 못하게 할 수있는 방법이 있습니까? 예 : 임베디드 매니페스트를 수정하거나 프로그램 방식을 통해?

관리자로 일반 앱을 실행하는 것은 매우 간단하지만 그 반대 일 수도 있습니다.

업데이트 : 나는 소스 코드 나 원본 매니페스트 파일이 아니라 컴파일 된 .exe에만 액세스 할 수 있습니다. 나는 케니 커에 의해 ManifestView 통해 .EXE의 포함 된 매니페스트를 살펴 했어 그 다음이 포함로 확실히 관리자 권한을 요청

<requestedPrivileges> 
    <requestedExecutionLevel level="requireAdministrator" /> 
</requestedPrivileges> 

는 컴파일의 매니페스트를 변경할 수있는 방법이 있습니까. exe 어셈블리? 예 : 프로그래밍을 통해이를 수행하는 방법에 대한 정보 나 정보를 제공하는 도구는 무엇입니까?

+0

http://stackoverflow.com/questions/8784692/how-to-avoid-user-account-control-or-run-windows-application-in-win7-always-in-a –

+0

@ 제이슨 그것은 여기서 요구되는 것과는 정반대 인 것처럼 보입니다. – cHao

+0

@cHao : 그러나이를 사용하면 매니페스트가 변경 될 수 있음을 알 수 있습니다. –

답변

1

임베디드 매니페스트를 수정하여 관리자 권한을 요청하지 않도록 작은 C# 응용 프로그램을 만들려고했습니다. 이것은 마침내 내놓은 솔루션으로, 매니페스트를 추출하고 기존 매니페스트를 바꾸기위한 Win32 호출을 많이 만듭니다. 이미 충분히 길기 때문에 실제로 매니페스트 (일부 기본 XML 작업)를 수정 한 부분은 생략했습니다.

여기에 두 개의 정적 방법이 있습니다 : 지정된 실행 파일에 매니페스트 리소스의 문자열 표현을 저장 실행 및 SaveManifestResource의 임베디드 매니페스트의 문자열 표현을로드 LoadManifestResource, 이전 것을 덮어 쓰기가 .

이것은 나를 위해 잘 작동하지만 모든 경우에 잘 작동하지 않는 빠르고 더러운 솔루션입니다.

public static class Library 
{ 
    [DllImport("kernel32.dll")] 
    static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool FreeLibrary(IntPtr hModule); 

    [DllImport("kernel32.dll")] 
    static extern IntPtr FindResource(IntPtr hModule, int lpName, int lpType); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo); 

    [DllImport("kernel32.dll")] 
    static extern IntPtr LockResource(IntPtr hResData); 

    [DllImport("Kernel32.dll", EntryPoint = "SizeofResource", SetLastError = true)] 
    private static extern uint SizeofResource(IntPtr hModule, IntPtr hResource); 

    [System.Flags] 
    enum LoadLibraryFlags : uint 
    { 
     DONT_RESOLVE_DLL_REFERENCES = 0x00000001, 
     LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010, 
     LOAD_LIBRARY_AS_DATAFILE = 0x00000002, 
     LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040, 
     LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020, 
     LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008 
    } 

    public static unsafe string LoadManifestResource(string fileName) 
    { 
     // load library to retrieve manifest from 
     var libraryHandle = LoadLibraryEx(fileName, IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE); 
     if (libraryHandle.ToInt32() == 0) 
     { 
      throw new Win32Exception(Marshal.GetLastWin32Error(), "couldn't load library"); 
     } 
     try 
     { 
      // find manifest 
      var resource = FindResource(libraryHandle, 1, 24); 
      if (resource.ToInt32() == 0) 
      { 
       throw new Win32Exception(Marshal.GetLastWin32Error(), "couldn't find manifest resource"); 
      } 

      // load manifest 
      var loadedManifest = LoadResource(libraryHandle, resource); 
      if (loadedManifest.ToInt32() == 0) 
      { 
       throw new Win32Exception(Marshal.GetLastWin32Error(), "couldn't load manifest resource"); 
      } 

      // lock manifest 
      var lockedManifest = LockResource(loadedManifest); 
      if (lockedManifest.ToInt32() == 0) 
      { 
       throw new Win32Exception(Marshal.GetLastWin32Error(), "couldn't lock manifest resource"); 
      } 

      // calculate size of manifest, copy to byte array and convert to string 
      int manifestSize = (int)SizeofResource(libraryHandle, resource); 

      byte[] data = new byte[manifestSize]; 
      Marshal.Copy(lockedManifest, data, 0, manifestSize); 
      var manifest = Encoding.UTF8.GetString(data); 

      return manifest; 
     } 
     finally 
     { 
      FreeLibrary(libraryHandle); 
     } 
    } 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern IntPtr BeginUpdateResource(string pFileName, 
     [MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern bool UpdateResource(IntPtr hUpdate, int lpType, int lpName, ushort wLanguage, IntPtr lpData, uint cbData); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard); 

    public static unsafe void SaveManifestResource(string file, string manifest) 
    { 
     var hUpdate = BeginUpdateResource(file, false); 

     byte[] bytes = Encoding.UTF8.GetBytes(manifest); 
     IntPtr ptr = Marshal.AllocHGlobal(bytes.Length); 
     try 
     { 
      Marshal.Copy(bytes, 0, ptr, bytes.Length); 

      if (!UpdateResource(hUpdate, 24, 1, 0, ptr, (uint)bytes.Length)) 
      { 
       throw new Win32Exception(Marshal.GetLastWin32Error()); 
      } 

      if (!EndUpdateResource(hUpdate, false)) 
      { 
       throw new Win32Exception(Marshal.GetLastWin32Error()); 
      } 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(ptr); 
     } 
    } 
} 
0

Admini 권한이 필요한 앱에 코드가있는 경우 앱을 실행할 수 없다고 생각합니다.

일부 코드/apis에는 특정 권한이 필요합니다. 그래서 나는 당신이 그것을 통과 할 수 있다고 생각하지 않는다 :/

내가 볼 수있는 유일한 해결책은 당신이로드하거나로드하지 않을 모듈로 유죄 코드를 구분하는 것이다. 따라서 동일한 제품을 유지하면서 두 버전을 모두 실행해야합니다.

+0

미안하지만, 질문의 앞부분에서 말했듯이 : 나는 소스 코드에 액세스 할 수 없으므로 코드를 별도의 모듈로 옮길 수는 없습니다. 음, 아마도 de-와 recompiling을 통해 나는 피할 수 있다면 오히려 거기에 가지 않을 것입니다. – Mario

관련 문제