2017-12-01 5 views
0

ショートカットのアイコンをフォルダに設定しようとしていますが、ショートカットアイコンをshell32.dllのネイティブアイコンに設定する方法に関するリソースが見つかりません。私はThisがRyklerによってmsdnで答えを見つけましたが、答えは古くなっています。どんな助けもありがとう。ショートカットアイコンとしてshell32.dllのアイコンを使用

コード

SHFILEINFO shinfo = new SHFILEINFO(); 
Win32.SHGetFileInfo(filename, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), (int)0x1000); 
// icon index # and path 
int IconIndex = shinfo.iIcon 
string IconPath = shinfo.szDisplayName 
shortcut.IconLocation = ??? 

SHFILEINFO構造体:This質問から撮影)

[StructLayout(LayoutKind.Sequential)] 
public struct SHFILEINFO 
{ 
    public IntPtr hIcon; 
    public int iIcon; 
    public uint dwAttributes; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public string szDisplayName; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 
    public string szTypeName; 
}; 

class Win32 
{ 
    [DllImport("shell32.dll")] 
    public static extern IntPtr SHGetFileInfo(string pszPath, uint 
dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); 
} 
+0

を使用すると、エラーメッセージを持っていつでも、それはあなたの質問の一部としてそれを共有することをお勧めします「が、Visual Studioは、エラーがスローされます」。 – itsme86

+0

メソッドのオーバーロードがありません 'ExpandEnvironmentStrings'は2つの引数をとります。私が見ていた答えは時代遅れだと思います。 –

+0

'ExpandEnvironmentStrings'があなたのコードに表示されないので、どうしたらエラーになるのですか? – NetMage

答えて

0

ので、少し研究した後、あまりにも複雑ではないようです。まず、インターフェイス宣言をthis questionから取得します。プロジェクトに宣言を含めます。その後

、あなたはこのコードを使用することができます:追加する

public class Q47602417 
{ 
    public static void MakeShortcut(string targetPath) 
    { 
     var shellLink = new ShellLink(); 
     ((IShellLinkW)shellLink).SetDescription("Sample Shortcut"); 
     ((IShellLinkW)shellLink).SetPath(targetPath); 
     ((IShellLinkW)shellLink).SetIconLocation(Environment.SystemDirectory + "\\Shell32.dll", 12); 
     ((IPersistFile)shellLink).Save(@"C:\temp\shortcut.lnk", false); 
    } 
} 

一つのこと:このサンプルではエラーチェックが含まれていませんが!ショートカットが作成されたかどうかはわかりません。したがって、呼び出されたインターフェイスメソッドを変更して整数を返し、例外チェックを追加します。

//... 

int SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); 
int SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); 
int SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); 

//.. omitted other details ... 

int Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [In, MarshalAs(UnmanagedType.Bool)] bool fRemember); 

これで、ショートカットの作成が正しく機能するかどうかを確認できます。

public class Q47602417 
{ 

    public static void MakeShortcut(string targetPath) 
    { 
     ShellLink shellLink = new ShellLink(); 
     int hr; 
     hr = ((IShellLinkW)shellLink).SetDescription("Sample Shortcut"); 
     Marshal.ThrowExceptionForHR(hr); 

     hr = ((IShellLinkW)shellLink).SetPath(targetPath); 
     Marshal.ThrowExceptionForHR(hr); 

     hr = ((IShellLinkW)shellLink).SetIconLocation(Environment.SystemDirectory + "\\Shell32.dll", 12); 
     Marshal.ThrowExceptionForHR(hr); 

     hr = ((IPersistFile)shellLink).Save(@"C:\temp\shortcut.lnk", false); 
     Marshal.ThrowExceptionForHR(hr); 
    } 

} 

例の結果:

enter image description here

+0

かなりひどいですね、私がリンクした投稿を考えてみてください。明示的なエラーチェックの必要もなく、COMエラーコードは自動的にCLR例外になります。 –

+0

私はそれがひどいと思いますが、エラーチェックと書き込み禁止フォルダなしで上記のコードを試してみましたが、 'Save'の呼び出しでCLR例外がありませんでした。私はオートメーションオブジェクトについて読んだことがありますが、私はダイレクトコールを介して他の方法を利用しました。私はその話題で実世界の経験が足りないので、どの方法がより優れているのか、それ以上の将来性があるのか​​を判断することはできません。しかし、私はこの種のエラーチェックがひどいことに同意します。 – ventiseis

+0

もう一つのことは、元の質問が少し不明であることです:なぜ彼は 'SHGetFileInfo'を使用していますか? [この質問](https://stackoverflow.com/questions/1599235/how-do-i-fetch-the-folder-icon-on-windows-7-using-shell32-shgetfileinfo)のフォルダアイコンの取得ハンドル。だから質問者が特定のフォルダのアイコンを望むなら、彼はそのコード部分を '.ico'に格納し、それをショートカットのアイコンとして使う必要があります。または私は何かを逃していますか? – ventiseis

関連する問題