Question

I have an old VB6 application that saves its data to an ini file, which it expects to be in the windows folder. In the VB6 code, I just refer to the file name (without path) and it is located automatically by Windows in the Windows folder. On Windows 8 and corporate networks however, windows moves the file to the user account, so it appears under the \Users\username\AppData folder structure.

VB6 couldn't care less, it always reads "ipmdata.ini" and gets the user specific one handed to it by Windows from the AppData folder.

However, I now need to read this same ini file from a C# application. So I added the definitions for GetPrivateProfileString and fed it with the same parameters I give to VB6. The C# code always reads from the file in the windows folder, not the same file that VB6 is reading and writing.

Any ideas how I make the C# call do the same as the VB6 call to the same API?

I have tried targeting the .Net application against Framework 2.0, compiling to x86 and running editbin to set /TSAWARE:NO on the final executable (though I do not know how to check that works - it just didn't 'fail').

The VB6 code consists of a declare and a read:

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")

The equivalent code in the c# application consists of:

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

There is nothing else in the test programs just this code to read the ini file. The C# code reads the ini currently in my \Windows folder and the VB6 code reads from the \users\user\appdata\virtualstore\windows folder.

Was it helpful?

Solution

Lots of misconceptions here.

UAC began back in 2006 with Windows Vista, not Windows 8.

Filesystem virtualization is not an application feature, but a bug. Programmers have been explicitly warned by Microsoft not to rely on it.

Your .Net program probably has a manifest marking it as Vista Aware, in which case virtualization never applies.

This also appears to be a duplicate of Force an existing application to always run with UAC virtualization on

Basicaly the real answer is to fix your program so that it doesn't need virtualization.

OTHER TIPS

Have you tried specifying the complete path?

GetPrivateProfileString("PCD", "TemplateFolder", "", sb, 2048, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mystuff.ini");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top