locked
Windows10 での symlink RRS feed

  • General discussion

  • こんにちは、Platform SDK (Windows SDK) サポートチームです。

    今回は、Windows 10 および Windows 8.1/7 において、シンボリック リンクを指定して ShellExecute を呼び出した時の動作の差異についてお伝えします。

     

    現象

    ========

    Windows 10 の環境において、アプリケーションのシンボリック リンクを指定して、 ShellExecute でプロセスを起動した場合は、シンボリック リンクと同じディレクトリに存在する DLL を読み込めない場合があります。

    Windows 8.1/7 の環境では、この現象が発生しません。

     

    例:

    以下のフォルダ構成があると仮定します。

    .NET Framework において、 ProcessStartInfo.UseShellExecute true へ設定した状態で、test.exe のシンボリンクパス(c:\Folder-A\test.exe) を指定してプロセスを起動した場合には、 test.dll が参照できないとの例外エラーが発生します。

     

    - Folder-A には、 test.exe のシンボリック リンクを作成します。 test.dll の実体はシンボリック リンクと同じフォルダ Folder-A に格納します。

    - Folder-B には、 test.exe の実体を格納します。 test.exe は、 Folder-A 内の test.dll を参照します。

    test.exe test.dll C#で作成しています。

     

    Folder-A:

    <SYMLINK> test.exe [c:\Folder-B\test.exe]

              test.dll

     

    Folder-B

              test.exe

     

     

    原因

    ========

    ProcessStartInfo.UseShellExecute true へ設定した状態でプロセスを起動した場合には、ShellExecute が内部にて実行されます。

    Windows 10では、 ShellExecute にて、シンボリックリンクを指定した場合は、シンボリック リンク先のパスで CreateProcess が実行されます。

    アプリケーションが参照する DLL がシンボリック リンク先のパスに格納されていないと、下記のドキュメントに記載されておりますアセンブリの検索順番にて、DLLの検索が失敗します。

     

    [ランタイムがアセンブリを検索する方法]

    https://docs.microsoft.com/ja-jp/dotnet/framework/deployment/how-the-runtime-locates-assemblies

     

     

    状況

    ========

    Windows 10 においては、下記ブログにも記載されておりますように、シンボリック リンク作成時の動作に重要な変更が加えられております。従来の Windows では、シンボリック リンクを作成する際にデフォルトで管理者権限を必要としておりましたが、 Windows 10 では、 管理者権限がなくとも、 シンボリック リンクを作成することができるように動作が変更されております。

    Windows 10から、シンボリック リンク関連の変更に伴い、windows.storage.dll という新しいモジュールにて IShellLink として実装されている箇所の機能が追加され、シンボリック リンクを解決し、リンク先のパスにてプロセスが実行されるように実装されております。

    一方、Windows 8.1/7 には  CreateProcessW を呼び出すまでにシンボリック リンクが解決される処理がないため、プロセスの実行パスはシンボリック リンクの存在するパスとなっておりました。

    そのため、 Windows 8.1/7 Windows 10 では、シンボリック リンクを指定して、 ShellExecute を実行した場合に、プロセスの実行パスに変化が生じておりました。

     

        [Symlinks in Windows 10!]

        https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/#SU5PYGcrs6ShXZRQ.97

     

     

    回避策

    ========

    アプリケーションが参照するDLLをシンボリック リンク先のパスに配置することを検討してください。

    Monday, November 25, 2019 8:45 AM
    Owner