UACで昇格 by manifest in C#

アプリケーションの実行時にsuが欲しいときは、app.exe.manifestを使うといいらしい。

from http://blogs.msdn.com/tsmatsuz/archive/2006/11/01/windows-vista-uac.aspx

以下コピペ。WindowsApplication1は変更すること。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="WindowsApplication1" type="win32"/>
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
      <security>
         <requestedPrivileges>
            <requestedExecutionLevel level="requireAdministrator"/>
         </requestedPrivileges>
      </security>
   </trustInfo>
</assembly>

 

で、VS2005とかだとあれこれしなきゃいけない。けど、VS2008からはもっと楽な方法がある。

①とりあえず作ったapp.exe.manifestをプロジェクトに参加させる

②プロジェクトのプロパティ画面を開く

③アイコンとマニフェスト→マニフェスト で app.exe.manifestを選択

以上。楽ですね。

カーソルをリソースからセットする。

Step 1.カーソルをリソースからロードする

なんというか、いろいろ迷いがち。

public Cursor(Type type,string resource); 

なんていうコンストラクタがあるけど、使ったら負け。

ストリームで返せって言ってるので、素直にMemoryStreamを使いましょう。 例:

var csor = new Cursor(new MemoryStream(Properties.Resources.csor)); 

ただし。

これで読むと、カーソルは白黒になります。

メモ Cursor クラスでは、アニメーション カーソル (.ani ファイル)、またはカラーのカーソルはサポートされていません。

http://msdn.microsoft.com/ja-jp/library/system.windows.forms.cursor%28VS.71%29.aspx

仕様です。仕様かーそーなのかー。

でも他のアプリケーションはバリバリカラーですね。どうしましょう。

Step 2.カーソルをカラーでリソースからロードする

カラーで読む方法は無いのかって?あるんです。

Icon icon = new Icon(@"orignal.ico");
Cursor cur = new Cursor(icon.Handle);
Cursor = cur;

ただし、ホットスポットは中心になります。なんとまぁ使えない

Step 3.最終奥義

困った時のWinAPI。

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]  
extern public static IntPtr LoadImage(IntPtr Instance, String Name, uint Type, int xDesired, int yDesired, uint LoadOption);  
public static System.Windows.Forms.Cursor LoadCursor(String LoadCursorName)
{
         IntPtr ptr = LoadImage(IntPtr.Zero, LoadCursorName, 2, 0, 0, 0x10 | 0x40);
        if (ptr == IntPtr.Zero)
        {
            throw new Exception("カーソルのロードに失敗しました。(" + Marshal.GetLastWin32Error() + ")");
       }
       return new System.Windows.Forms.Cursor(ptr);  
}
  

これで、リソースを一旦ファイルにして読めばいいと思うよ!ほら、GetTempFileNameとかあるし!

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
extern public static IntPtr LoadImage(IntPtr Instance, String Name, uint Type, int xDesired, int yDesired, uint LoadOption); 
public static System.Windows.Forms.Cursor LoadCursor(String LoadCursorName) 
{ 
       IntPtr ptr = LoadImage(IntPtr.Zero, LoadCursorName, 2, 0, 0, 0x10 | 0x40); 
      if (ptr == IntPtr.Zero) 
      { 
          throw new Exception("カーソルのロードに失敗しました。(" + Marshal.GetLastWin32Error() + ")"); 
     } 
     return new System.Windows.Forms.Cursor(ptr); 
} 

以上、備忘録。つかれた。

細かいところTypict 1.xのソースからパクったからバグあるかも。あと、Dispose関連は緩め。気をつけてね。(MemoryStreamに関してはCloseいらないみたいだけど)