使用C#,如何获取“Ap​​plication.StartupPath”以返回映射的驱动器路径而不是UNC路径?

时间:2013-01-08 19:35:24

标签: c# uac

当我的应用程序使用app.manifest时,下面的行设置如图所示

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

代码

textBox1.Text = Path.Combine(Application.StartupPath, "setupws.exe");

返回"\\server\myApp\setupws.exe"

如果我将requestedExecutionLevel更改为"asInvoker",或完全删除app.manifest,则会返回"F:\myApp\setupws.exe"。这就是我需要的。

有没有办法让Application.StartupPath按照我想要的方式行事,仍然使用requireAdministrator

1 个答案:

答案 0 :(得分:2)

我无法想办法改变你的反应,但是你总是可以尝试将UNC重新映射到当地 - 为此,你需要召唤出来使用&#34;平台调用&#34;或&#34; PInvoke&#34;到基础Win32调用(C dll调用);引用win32调用的语法有点像:

[DllImport("mpr.dll", CharSet=CharSet.Auto, SetLastError=true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool WNetGetConnection(
    [MarshalAs(UnmanagedType.LPTStr)] string localName, 
    [MarshalAs(UnmanagedType.LPTStr)] StringBuilder remoteName, 
    ref int length);

(这样做是将非托管呼叫/类型映射到他们的托管等价物,以及告诉编译器&#34;嘿,除了这些东西之外我还有其他代码调用&#34)

WNetGetConnection是一个相当笨拙的Windows功能:给它一个驱动器号,如果它映射到一个路径,你将返回一个UNC路径。我们将循环显示已知的驱动器号码,然后依次为每个呼叫提供此呼叫,如果我们与返回的UNC名称和我们尝试的路径进行任何部分匹配&#34;反向地图&#34;,我们将用相应的驱动器号替换路径的UNC部分,我们已完成:

public string GetLocalPathForUnc(string uncName)
{
    var mapped = Environment.GetLogicalDrives().Select(drive => 
    {
        drive = drive.Substring(0,2);
        var buffer = new StringBuilder(0xff);
        int length = 0xff;
        WNetGetConnection(drive, buffer, ref length);
        return new {Drive = drive, Unc = buffer.ToString()};
    });
    var match = mapped
            .Where(ob => 
                 !string.IsNullOrWhiteSpace(ob.Drive) && 
                 !string.IsNullOrWhiteSpace(ob.Unc))
        .FirstOrDefault(ob => uncName.ToLowerInvariant().StartsWith(ob.Unc.ToLowerInvariant()));
    return uncName.Replace(match.Unc, match.Drive);
}