2014-01-26 112 views
2

我有一箇舊的VB6應用程序將其數據保存到一個ini文件,它希望它在Windows文件夾中。在VB6代碼中,我只是指向文件名(沒有路徑),它由Windows在Windows文件夾中自動定位。但是,在Windows 8和公司網絡上,Windows將文件移動到用戶帳戶,因此它出現在\ Users \ username \ AppData文件夾結構下。閱讀本地帳戶ini文件

VB6並不在意,它總是讀取「ipmdata.ini」,並從AppData文件夾中獲取Windows提供的特定用戶。

但是,我現在需要從C#應用程序讀取這個相同的ini文件。所以我添加了GetPrivateProfileString的定義,並給它提供了與VB6相同的參數。 C#代碼總是從windows文件夾中讀取文件,而不是VB6正在讀取和寫入的文件。

任何想法如何使C#調用做相同的VB6調用相同的API?

我已經嘗試了針對Framework 2.0的.Net應用程序,編譯爲x86並運行editbin來設置/ TSAWARE:NO上的最終可執行文件(儘管我不知道如何檢查該功能 - 它只是沒有'失敗')。

VB6的代碼包含一個聲明和讀的:

Public Declare Function GetPrivateProfileString Lib "kernel32" _ 
    Alias "GetPrivateProfileStringA" (_ 
    ByVal lpApplicationName As String, _ 
    ByVal lpKeyName As Any, _ 
    ByVal lpDefault As String, _ 
    ByVal lpReturnedString As String, _ 
    ByVal nSize As Long, _ 
    ByVal lpFileName As String) As Long 

    nRetcode = GetPrivateProfileString("PCD", "TemplateFolder", "", sTemp, 512, "mystuff.ini") 

在C#應用程序的等效代碼包括:

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] 
    static extern uint GetPrivateProfileString(
     string lpAppName, 
     string lpKeyName, 
     string lpDefault, 
     StringBuilder lpReturnedString, 
     uint nSize, 
     string lpFileName); 

     StringBuilder sb = new StringBuilder(2048); 
     GetPrivateProfileString("PCD", "TemplateFolder", "", sb, 2048, "mystuff.ini"); 

沒有什麼別的測試程序恰好這個代碼閱讀ini文件。 C#代碼讀取當前在我的\ Windows文件夾中的ini,並從\ users \ user \ appdata \ virtualstore \ windows文件夾中讀取VB6代碼。

+1

如果您在當前使用的VB和C#中顯示讀取ini文件的相關代碼,這將有所幫助。如果你只是在VB中使用私有聲明函數GetPrivateProfileString Lib「kernel32」',並且在C#中使用'[DllImport(「kernel32.dll」] static extern uint GetPrivateProfileString()',我懷疑API調用會導致這種行爲,因爲它們是也可能有其他代碼干擾路徑,或者API調用在當前目錄中查找,這可能會因不同的應用程序而有所不同 – CodeCaster

+0

另外,當移植依賴於[古代WinAPI調用](http ://msdn.microsoft.com/en-us/library/windows/desktop/ms724353(v = vs.85).aspx),您可能需要考慮[使用庫](https://code.google。 com/p/ini-parser /)來替換它們。 – CodeCaster

+0

由於您正在將應用程序移植到.NET,爲什麼不移植.ini呢?您可以將設置添加到app.config文件。配置文件存儲在與應用程序相同的文件夾中。這是一個MSDN文章,其中有更詳細的解釋。 http://msdn.microsoft.com/en-us/library/a65txexh.a​​spx – jac

回答

0

這裏有很多誤解。

UAC在2006年就開始背了Windows Vista,而不是Windows 8

文件系統虛擬化是不是一個應用程序的功能,但一個錯誤。微軟明確警告程序員不要依賴它。

您的.Net程序可能有一個標記爲Vista Aware的清單,在這種情況下,虛擬化從不適用。

這也似乎是Force an existing application to always run with UAC virtualization on

Basicaly的副本,真正的答案是修復您的程序,以便它不需要虛擬化。

+0

我同意,這感覺就像一個bug。可悲的是,這是一個我需要忍受的錯誤。我將我的.net應用程序修改爲32位,並添加了一個應該啓用虛擬化的清單。沒有工作。我的感覺是,當程序編譯成虛擬化時,背景中正在發生其他事情。我在虛擬機上有一個VS2008的舊副本,並會嘗試在那裏構建應用程序,看看它是否有任何區別。虛擬化不是我想要使用的東西,也不是我要求的東西。它被強加給我。 – sab

+0

然後只複製文件虛擬化進程的行爲,而不是嘗試*使用虛擬化。查找虛擬化的INI,如果沒有,則通過從Windows文件夾中複製一個,在那裏創建它。 – Bob77

+0

由於它自己的問題,因爲api沒有找到虛擬化文件夾被調用的方法,並且我無法對該名稱進行硬編碼,因爲它可以被本地化。對於這個應用程序的目的,我想我開始在任何文件夾包含AppData和執行遞歸搜索,直到我找到ini文件或用完的地方看。對於這個特定的應用程序,我可以逃避。只是使用已發佈的界面會很好。 – sab

0

您是否試過指定完整路徑?

GetPrivateProfileString("PCD", "TemplateFolder", "", sb, 2048, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mystuff.ini"); 
+0

是的,無論我指定完整路徑還是沒有路徑,都無關緊要。 – sab

+0

@sab我不明白,因爲我測試之前,我張貼,它從預期的文件夾抓住。 – jac

+0

你在做什麼是不同的。你已經專門去了AppData文件夾。 VB6代碼寫入它認爲是Windows文件夾,Windows重定向到虛擬文件夾。 C#中的相同代碼不會重定向。我需要實現的是讓Windows以與VB6相同的方式處理我的.NET代碼,並將其重定向到虛擬化的Windows文件夾。 – sab