【发布时间】:2014-02-17 05:48:41
【问题描述】:
我有一个旧的 VB6 应用程序,它将其数据保存到一个 ini 文件中,它希望该文件位于 windows 文件夹中。在 VB6 代码中,我只引用文件名(不带路径),它由 Windows 自动定位在 Windows 文件夹中。然而,在 Windows 8 和企业网络上,Windows 将文件移动到用户帐户,因此它出现在 \Users\username\AppData 文件夹结构下。
VB6 不在乎,它总是读取“ipmdata.ini”并从 AppData 文件夹中获取由 Windows 交给它的用户特定的一个。
但是,我现在需要从 C# 应用程序中读取相同的 ini 文件。所以我添加了 GetPrivateProfileString 的定义,并用我给 VB6 的相同参数提供给它。 C#代码总是从windows文件夹中的文件读取,与VB6正在读写的不是同一个文件。
有什么想法可以让 C# 调用与 VB6 调用相同的 API 一样吗?
我尝试将 .Net 应用程序针对 Framework 2.0,编译为 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,VB6 代码从 \users\user\appdata\virtualstore\windows 文件夹中读取。
【问题讨论】:
-
如果您在当前使用的 VB 和 C# 中显示用于读取 ini 文件的相关代码,将会有所帮助。如果您只使用 VB 中的
Private Declare Function GetPrivateProfileString Lib "kernel32"和 C# 中的[DllImport("kernel32.dll"] static extern uint GetPrivateProfileString(),我怀疑 API 调用会导致这种行为,因为它们是相同的。可能有其他代码干扰了路径,或者 API 调用在当前目录中查找,对于不同的应用程序可能会有所不同。 -
另外,当移植依赖于此类ancient WinAPI calls 的应用程序时,您可能需要考虑用using a library 替换它们。
-
既然要将应用程序移植到 .NET,为什么不也移植 .ini 呢?您可以将设置添加到 app.config 文件。配置文件与应用程序存储在同一文件夹中。这是一篇 MSDN 文章,其中有更详细的解释。 msdn.microsoft.com/en-us/library/a65txexh.aspx
-
对不起,我没有收到任何关于 cmets 的通知。我将使用代码更新帖子。但是,作为测试,我将其剥离到绝对最低限度。所以有一个测试 VB6 程序,它由一个声明和一个具有相同有限代码的 C# 程序组成。我没有移植应用程序。我有一个需要在 .Net 中完成的新要求。旧的 vB6 应用程序将保持原样。
-
仅供参考,我现在已将清单嵌入到应用程序中,并明确更改了安全选项以启用虚拟化。在尝试读取它之前,我还更改了程序以写入 ini 文件。可悲的是,没有区别; VB6 读取虚拟的,.Net 读取真实的。我想我会写代码先去寻找虚拟化的ini文件,如果我找不到虚拟化的文件,就只读取windows一个。这是一个垃圾解决方案,但可能是我拥有的最好的解决方案。