• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1419
  • Last Modified:

how to rebuild an Ini file using WritePrivateProfileString

Please note, although this deals with PDF995, the question is generic and could apply to any application that needs to restore an INI file to its original values.

I have a PDF995 ini file that starts out with 4 lines looking like this.
   [Parameters]
    clearInstall=1
    Quiet=0
    Use GPL Ghostcript=1

When my macro is done I want to the inifile to look exactly the same.  (My macro adds many parameter, but they are all temporary in nature.)

The code at the end of this post seems to work in windows 7, but I get weird results in windows xp: when the application is done running, an undesired Explorer window pops up displaying a PDF995 subfolder.

I noticed that lines 16 to 20 are not using kernel32 API whereas the rest of the macro does use an API. I think this inconsistency led to the weird behavior.

My theory led to a successful workaround. I replaced lines 16 to 20 with the following.  
    desired = ""
    desired = desired & "AutoLaunch=,"
    desired = desired & "Autostamp=,"
    desired = desired & "Diagonal Stamp=,"
    desired = desired & "Output File=,"
    desired = desired & "Stamp Text=,"
    desired = desired & "Stamp Text=,"
    desired = desired & "Stamp Text=,"
    desired = desired & "X Position Stamp=,"
    desired = desired & "Y Position Stamp=,"
    desired = desired & "User File=,"
    desired = desired & "Launch=,"
    desired = desired & "Document Name=,"

Open in new window


But, I do not like that workaround because it does not return the ini file to its exact initial setting.  Also, any time a higher level subroutine starts to use a different parameter, I have to remember to add the parameter to the workaround.


Here is the original code, before the workaround.

Sub ChangeIni(ByVal desired As String, iniFilename As String, Optional delim As String = ",")


' windows xp first and windows 7 second
If InStr(1, Environ("Appdata"), "Roaming", 1) = 0 Then
    iniFilename = "c:\pdf995\res\pdf995.ini"
    Pdf995syncFilename = "C:\pdf995\res\pdfsync.ini"
Else
   iniFilename = "C:\Program Files (x86)\pdf995\res\pdf995.ini"
   Pdf995syncFilename = "C:\ProgramData\pdf995\pdfsync.ini"
End If

' to restore all values to PDF995 defaults        call changeini("clear",infilename)
Dim intFileNum As Long
If LCase(desired) = "clear" Then
    intFileNum = FreeFile()
    Open iniFilename For Output As intFileNum
        
    Print #intFileNum, "[Parameters]"
    Close intFileNum
    desired = desired & "Install=1,"     ' from Ini file after fresh install
    desired = desired & "Quiet=0,"     ' from Ini file after fresh install
    desired = desired & "Use GPL Ghostcript=1,"     ' from Ini file after fresh install
End If
        
If Len(delim) > 1 Then Stop
If Right(desired, 1) = "," Then
    desired = Left(desired, Len(desired) - 1)
End If

Dim ary
Dim I As Long
Dim ub As Long
    Dim paramFull As String
    Dim paramName As String
    Dim paramDesiredValue As String

    Dim ix As Long
ary = Split(desired, delim)

ub = UBound(ary)
If Len(ary(ub)) = 0 Then ub = ub - 1
For I = 0 To ub

    paramFull = ary(I)
    ix = InStr(paramFull, "=")
    paramName = Left(paramFull, ix - 1)
    paramDesiredValue = Mid(paramFull, ix + 1)
    Dim x
    If InStr(paramDesiredValue, ",") Then Stop
    x = WritePrivateProfileString("PARAMETERS", paramName, paramDesiredValue, iniFilename)
    ' x = WritePrivateProfileString("PARAMETERS", "AutoLaunch", "0", inifilename)
Next I
End Sub

Open in new window

0
rberke
Asked:
rberke
3 Solutions
 
aikimarkCommented:
I'm not sure what the lines need to be, but you will probably need to add new line characters to the end of the lines.
    desired = ""
    desired = desired & "AutoLaunch=," & vbCrLf
    desired = desired & "Autostamp=," & vbCrLf
    desired = desired & "Diagonal Stamp=," & vbCrLf
    desired = desired & "Output File=," & vbCrLf
    desired = desired & "Stamp Text=," & vbCrLf
    desired = desired & "Stamp Text=," & vbCrLf
    desired = desired & "Stamp Text=," & vbCrLf
    desired = desired & "X Position Stamp=," & vbCrLf
    desired = desired & "Y Position Stamp=," & vbCrLf
    desired = desired & "User File=," & vbCrLf
    desired = desired & "Launch=," & vbCrLf
    desired = desired & "Document Name=," & vbCrLf

Open in new window

0
 
rberkeAuthor Commented:
no, my subroutine uses a comma as a delimiter.
0
 
David Johnson, CD, MVPOwnerCommented:
suggest you simply rename the current .ini, create your custom.ini and when done copy back the original.ini.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
aikimarkCommented:
When you say you get "weird results in XP" do you mean PDF995 behaves weirdly or that the .INI file looks weird or something else?
0
 
rberkeAuthor Commented:

Open in new window

Your idea does not work, but it helped me pin down the weirdness.

The undesired Explorer window pops up as soon as I try to Kill the old file.  But, if I put a sleep 1000 right before the Kill, the undesired windows DOES NOT pop up.
..... omitted code that creates a pdf file and waits for the file to be completely built...
Case "clear2"
    sleep 1000 ' < dropping this to 500 and the Explorer window starts popping 
    Kill iniFilename
    MsgBox "the unwanted explorer window is now showing"
    Exit Sub
    
End Select

Open in new window


I think the Microsoft API expects to be in complete control of the file.  When I do unexpected things, like killing the file, the API reacts badly.  It is also possible that the PDF995 code intercepts events related to the ini file which would absolve Microsoft of blame.  In either case, the only reliable solution is to reset the ini file entirely via an API.  

But, I now have another workaround which seems to work.  I put a Sleep 1000 right before line 16 in the original code.  Personally, I don't think this is as reliable as using the API to change the file.  I still hope somebody can tell me how to do that. I believe the folks who wrote the API must have included some sort of "Clear File" logic.
0
 
rberkeAuthor Commented:
aikamark:  as it says in my original post "I get weird results in windows xp: when the application is done running, an undesired Explorer window pops up displaying a PDF995 subfolder."
0
 
QlemoC++ DeveloperCommented:
Instead of fiddling with the INI, I really would go with http:#a38301293 ... As long as there are no changes to INI while executing which you need to retain.
0
 
rberkeAuthor Commented:
Qlemo, I had tried a38301293, but it did not work.  

It was judgement call on my part, so other folks might go with a modified version of a38301293

rename xxx.ini to .bak
create temporary xxx.ini
sleep 1000  < ===== required modification
kill xxx.ini     < ========== this step caused the unwanted popup unless the sleep statement is inserted.
rename xxx.bak to xxx.ini

Putting a sleep 1000 before the kill statement "fixed" the problem, but, I think it is an unreliable solution because I am mixing API control with direct control.  I suspect that under some situations 1 second, 2 seconds, or even 5 seconds might not be enough sleep time.  This kind of stuff is very touchy and it just feels wrong.  So, right at the moment, I am using my original workaround which only uses API calls. This is less likely to cause unpredictable results.  The disadvantages are minor: #1, it does not return the ini file to its exact initial setting, but it DOES return it to a functionally equivalent state.  #2 Any time a higher level subroutine starts to use a different parameter, I have to remember to add the parameter to the workaround.

It does not look like anybody is going to post a better solution, so I will close this question.
0
 
rberkeAuthor Commented:
Nobody had an ideal solution. I really think my solution is the safest, but I am giving most points to ve3ofa who provided an instructive alternative (which did not work until I added some cludges which I do not like).
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now