Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

App.EXEName problem. Help! 3

Status
Not open for further replies.

SharonLove

Programmer
Feb 26, 2003
18
DE
Who knows what causes the return value of the App.EXEName property to be always upper case on Win98 systems, but not on NT systems?

Example:
Actual Exe name is "MyApp.exe"

On Win98 systems (same VB run time files), App.EXEName returns the value: "MYAPP".
On NT: "MyApp"

Reason: Per customer request, I'm trying to do a binary comparison of the Exe name so if anyone changes the name to something different than desired, the application will not run.

If StrComp(App.EXEName, "MyApp", vbBinaryCompare) = 0 Then
'Ok
Else
End
End If
 
Why not format the returned value as either upper case or lower case. At that point both the question and the problem becomes moot.

HTH. Robert Berman
Data Base consultant
Vulcan Software Services
thornmastr@yahoo.com
 

Very fast answers! Amazing forum! You people are so sweet.

I realize that a Text comparison would return 0 (Ok).

The problem is that the client does not want the following being done:

mYaPp.Exe (=MyApp.Exe)

They want the exe name to read just as they requested, case sensitive.
 
LoveSharon

Can you tell which file system in in use on the NT machines.

Someone will correct me if I am wrong, but AFAIK the FAT & FAT32 do not preserve case while NTFS does.

i.e.
on FAT or FAT32 system
MyApp.exe is stored (in file allocation tables) as either myapp.exe or (as the results show more probably) MYAPP.EXE.

thus app.exename can only return MYAPP

NTFS is different and so app.exe will return the true case of the name.

As I said... I may well be wrong...

Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
The Win32 API is case-preserving (you can copy files and the case of the name will be preserved) but not case-sensitive; although under NTFS you can give a file names such as:

FILE1, File1, FiLe1

they are all considered equivalent. Just try saving files with these names in the same directory...

I'm not going to go into the problems that using the POSIX subsytem can cause as a result...
 

I'm using FAT on my developing pc (NT-4).

But, on all NT systems tested (NT 4, Win2000, Win XP) there are no problems.

Just on Win 98/95

So, does this mean it won't work the way requested?
 
Stromgm is right, doesn't matter if they user lower or upper case when changing the file's name regardles of Fat, Fat32 or NTFS, it will still be equivalent as long as the same letters are used in the same sequence.
You can still validate further filename changes though.
 
>So, does this mean it won't work the way requested?

Correct. Under W95/98/ME App.EXEName (which is really just a wrapper for the GetModuleFileNameA API call) returns the MS-DOS name, which is always in uppercase.
 
Don't know if you tried this (not to mention it may sound stupid) but...

open windows explorer / my computer
click tools (or is it 'view'?)
click folder options
click view tab
check/uncheck "allow all uppercase"
click apply

and see what happens (if anything).

--MiggyD
 
Curious, I just thought of this. What comes up when you list the directory? Does it match what's on Explorer/MyComp?

Ex:
[tt]
Directory of C:
CONFIG SYS 0 02-....28p CONFIG.SYS
WINDOWS <DIR> 02-....32p WINDOWS
MYDOCU~1 <DIR> 02-....49p [red]My Documents[/red]
PROGRA~1 <DIR> 02-....32p [red]Program Files[/red]
CONFIG BAK 0 02-....28p CONFIG.BAK
CABS <DIR> 02-....54p [red]cabs[/red]
AUTOEXEC BAT 194 02-....28p [red]Autoexec.bat[/red]
[/tt]

 
strongm,
that's sad.

How does explorer know then what case to use?
There must be some way of getting that value, or?

MiggyD,

I think you are on to something here.
In a DOS window I get the same on W98: Upper case for the actual DOS short name, but the correct case as a ?property?.

strongm and MiggyD
How would I get this property value?
Is it embedded in the EXE?
 
After my last post I was thinking about this. You should be able to do it as a two-step process:

a) retrieve that full path name for the file using GetModuleFilename
b) use a long-filename-aware call to access the correctly-cased filename using the path and filename returned by (a)

Here's one example that should work (have not actually tested on W95/98/Me however, as I am at work which is all NT/2000). You'll need a form with a command button, and a reference to the Microsoft Scripting Runtime library. I've created two functions to closely match both the App.EXEName and App.Path properties (two differences are that a) in the IDE the W9xEXEname function will return VB6.EXE rather than the project name; b) the W9xEXEName function includes the file's extension in the value it returns, whilst the native function does not). Then the following code:

[tt]
Option Explicit
Private Declare Function GetModuleFileName Lib &quot;kernel32&quot; Alias &quot;GetModuleFileNameA&quot; (ByVal hModule As Long, ByVal lpFilename As String, ByVal nSize As Long) As Long
Private Const MAX_PATH = 260


Private Sub Command1_Click()

MsgBox W9xAppPath
MsgBox W9xAppExe
End Sub

Private Function W9xAppEXEName() As String
Dim result As Long
Dim lpFilename As String
Dim fso As FileSystemObject

lpFilename = Space(MAX_PATH)
result = GetModuleFileName(0&, lpFilename, MAX_PATH)
Set fso = New FileSystemObject

W9xAppEXEName = fso.GetFileName(lpFilename)
Set fso = Nothing
End Function

Private Function W9xAppPath() As String
Dim result As Long
Dim lpFilename As String
Dim fso As FileSystemObject

lpFilename = Space(MAX_PATH)
result = GetModuleFileName(0&, lpFilename, MAX_PATH)
Set fso = New FileSystemObject

W9xAppPath = fso.GetAbsolutePathName(lpFilename)
Set fso = Nothing
End Function


 
That code is impressive and also seems obsessive for such a simple task; but I don't have access to NTs this month so maybe that's what is needed for that OE.

Two items that need to be addressed:
1)How to get a directory listing, and
2) Where to store the exact case spelling of the compiled program so that it is not easily changed.

1) = DIR()
2) = Application's Product Name Field

This may be a little late but it will return the correct info you are looking for on Win98 (without special controls/references/or API calls).


SETUP:
> new project
> one text box (long enough to see Filenames)
> four command buttons
> shut off ALL REFERENCES and ALL CUST. CTRLS (this is optional)
> ADD to App's 'ProductName' the EXACT Case-Sensitive filename spelling you want to use [red](see NOTE1 below)[/red]

THEN:
Paste following code, compile the project AND don't forget to compile it as the name you typed in exactly as is displayed in App.ProductName.



Private Sub Command1_Click()
Text1.Text = App.EXEName
End Sub

Private Sub Command2_Click()
Text1.Text = App.ProductName
End Sub

Private Sub Command3_Click()
Text1.Text = [red]Dir(&quot;*.*&quot;)[/red]
Do While Text1.Text <> Empty
If Text1.Text <> Empty Then
If StrComp([red]App.ProductName[/red], Text1.Text, 0) = 0 Then
MsgBox &quot;**** match made ****&quot;, , &quot;GREAT WORK!!!!&quot;
Exit Do
End If
MsgBox &quot;no match made&quot;, , &quot;Just Keep On Trying OK?&quot;
End If
Text1.Text = Dir
Loop
End Sub

Private Sub Command4_Click()
End
End Sub

Private Sub Form_Load()
Command1.Caption = &quot;App.EXE Name&quot;
Command2.Caption = &quot;app.product name&quot;
Command3.Caption = &quot;directory check&quot;
command4.Caption = &quot;exit&quot;
End Sub



Hopefully the above code and Setup instructions help.
--MiggyD


[red]NOTE1:[/red] When I compiled the project (lets say &quot;All for One&quot;) the extention was capitalized upon the first compilation...

All for One.[red]E[/red]xe

While ProductName was

All for One.[red]e[/red]xe

I exited the running prog., renamed it to a lower case '.exe' then a match was found.

Upon subsequent compilations it was compiled as lower case '.exe'
 
>obsessive for such a simple task

Huh? Apart from the Dims and the single API declaration, it only consists of 5 lines of actual code - and two of those can really be safely removed. So it is a 3-liner solution.

But since we're making comments, I'd observe a couple of problems with the alternative solution you provide:

1) I have to remember to set the Product Name property, which a) I might forget to set, and b) I might actually want it to contain a Product Name for some bizarre reason
2) Dir is relatively slow, particularly as directories grow larger
3) There are problems if the program is launched from a shortcut that specifies a different working directory, or of the program itself has explicitly changed it's working directory

The main problem with my solution is that, as given above, it doesn't actually do the job it is supposed to do! Under W9x/Me as it still returns an uppercase string (as I said I didn't have a box to test it on). However, this is easily fixed, eg:

[tt]
Option Explicit
Private Declare Function GetModuleFileName Lib &quot;kernel32&quot; Alias &quot;GetModuleFileNameA&quot; (ByVal hModule As Long, ByVal lpFilename As String, ByVal nSize As Long) As Long
Private Const MAX_PATH = 260

Private Function W9xAppEXEName() As String
Dim result As Long
Dim lpFilename As String
Dim fso As New FileSystemObject

lpFilename = Space(MAX_PATH)
result = GetModuleFileName(0&, lpFilename, MAX_PATH)
W9xAppEXEName = fso.GetFile(lpFilename).Name

End Function
[/tt]

>without special controls/references/or API calls

And the problem with using such features of the language is what?
 
What I meant by obsessive is that there seems to be too much tought put in to this, that's all. I tend to simplify things as much as possible and attemp to use the original code as much as possible so there isn't too much divertion for the original programmer to contend with. I still think your code is impressive all together.

>So it is a 3-liner solution. [I used her original code; modified 1 line. So mine is now a 1-liner solution. See updated code below.]

>I have to remember to set the Product Name property, which a) I might forget to set [so might I also forget to activate or add references, controls, etc.], and b) I might actually want it to contain a Product Name for some bizarre reason [I don't believe LoveSharon minds this small change in the whole scheme of things. Besides, it becomes part of the compiled program and is just as secure as your method is in obtaining the name.]

>Dir is relatively slow, particularly as directories grow larger [See updated code below]

>There are problems if the program is launched from a shortcut that specifies a different working directory, or of the program itself has explicitly changed it's working directory [See updated code below]

>And the problem with using such features of the language is what? [If it gets the job done, who am I to argue against it?]


'--Updated for slowness and if App is relocated or
' activated from a shortcut.
'
Private Sub Command3_Click()
If StrComp([red]App.ProductName[/red], [red]Dir(App.Path & &quot;\&quot; & App.ProductName)[/red], 0) = 0 Then
MsgBox &quot;**** match made ****&quot;, , &quot;GREAT WORK!!!!&quot;
Else
MsgBox &quot;no match made&quot;, , &quot;Just Keep On Trying OK?&quot;
End If
End Sub


Remember in programming, there is usually more than one way to do what you need to get done. I have my way and you have yours. I still say that your code is impressive.

--MiggyD
 

You cannot use the ProductName or ProductTitle like this, in order to see if the EXEName is what it should be, unless you settle for all three being the same.

Typically, you would have something like this:

App.ProductName = &quot;MyApp Database utility&quot;
App.Title = &quot;MyApp DbUtility&quot;
App.EXEName = &quot;MyApp&quot;


strongm:

1. What is the difference between your first and last examples?

2.
I would think that the following should work fine (with-out the GetModuleFileName function):

FileName = fso.GetFile(App.Path & &quot;\&quot; & App.EXEName & &quot;.exe&quot;).Name


And, to get the base name:
'FSO will return the DOS Base file name, so we cannot use that)
BaseFileName = &quot;Base Name = &quot; & Mid$(tmpDIR, 1, InStrRev(tmpDIR, &quot;.&quot;) - 1)
[/b][/i][/u][sub]*******************************************************
General remarks:
If this post contains any suggestions for the use or distribution of code, components or files of any sort, it is still your responsibility to assure that you have the proper license and distribution rights to do so!
 
Is fso.GetFile(X).Name the same as dir(X)?

strongm:

> 2) Dir is relatively slow, particularly as directories grow larger
I'm just curious. Dir is relatively slow compared to what? I've decided not to use fso just because it is very slow compared to dir (and some problems getting the really actual dir-sates while processing...). Have things changed? Or does performance change when the number of files in directories grow larger?
 
No, the point is that Dir as used (originally) in this solution had to iterate through (potentially) the whole folder file by file, which is slow. MiggyD addressed this in their most recent post.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top