2013-01-08 59 views
0

當我的應用程序正在使用的app.manifest,並且如果更改requestedExecutionLevel"asInvoker"下面的線設定爲示出使用C#,如何獲取「Ap​​plication.StartupPath」以返回映射的驅動器路徑而不是UNC路徑?

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

代碼

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

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

,或者完全刪除app.manifest,則返回"F:\myApp\setupws.exe"。這是我需要的。

有沒有辦法讓Application.StartupPath表現我想要的方式和仍然使用requireAdministrator

+1

爲什麼不直接將UNC路徑轉換爲映射驅動器路徑? –

+2

驅動器映射相對於*用戶*,UNC路徑相對於*無*。 – casperOne

+0

可能是因爲升級時映射的驅動器不存在。過去我曾經觀察過類似的東西,在所有的映射驅動器都不存在之後。所以說UNC是Windows可以提供給你的唯一東西? – Zarat

回答

2

我想不出有什麼辦法可以改變你得到的響應,但你總是可以嘗試將UNC重新映射回本地 - 爲此,你需要調用底層的Win32調用(C DLL調用)使用「平臺調用」,或「PInvoke」;用於參照W​​in32調用語法看起來有點像:

[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); 

(這是什麼東西做的是映射非託管的呼叫/類型的管理等同,以及告訴編譯器「嘿,還有代碼之外這個東西,我要打電話「)

WNetGetConnection是一個相當豪華的Windows功能:給它一個驅動器號,如果它映射到一個,你會得到一個UNC路徑。我們將循環訪問「已知驅動器號」,將每個驅動器依次提供給此調用,如果我們與返回的UNC名稱以及我們試圖「反轉映射」的路徑進行任何部分匹配,我們將替換具有相應驅動器號的路徑的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); 
} 
+0

那麼呢工作。但我可憐的初學者不知道它在做什麼。我可以忍受這一點! – JimDel

+0

哈 - 不用擔心,請添加一些說明文字。 :) – JerKimball

+0

@JimDel在那裏,有一個閱讀 - 希望它解釋得更好一點。 – JerKimball

相關問題