2012-03-19 30 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

@Jasonそれはここで尋ねられていることとは反対のようです。 – cHao

+0

@cHao:しかし、これは必要な可能性のあるマニフェストの可能な変更を洞察し、それを逆転させます。 –

答えて

1

埋め込みマニフェストを修正して管理者権限を要求しないように、小さなC#アプリケーションを作成しようとしました。これは私が最終的に思いついた解決策であり、マニフェストを抽出して既存のマニフェストを置き換えるWin32呼び出しをたくさん作成しています。すでに十分な長さなので、実際にマニフェストを変更する部分(省略時のXML操作)は省略しました。

ここでは2つの静的メソッドがあります。指定された実行可能でマニフェストリソースの文字列表現を保存し、実行し、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

申し訳ありませんが、私はソースコードにアクセスできないので、コードを別のモジュールに移動することはできません。さて、デコンパイルと再コンパイルを行うと、おそらく避けることができれば、そこに行くのではないでしょう。 – Mario

関連する問題