PathYetAnotherMakeUniqueName or PathMakeUniqueName API call from C#

  • Thread starter Thread starter Paul Welter
  • Start date Start date
P

Paul Welter

I'm having trouble getting the api PathYetAnotherMakeUniqueName to work.
Here is what I have so far. It is not working. What am i missing?

const int MAX_PATH = 260;

[DllImport("shell32.dll", EntryPoint="PathMakeUniqueName")]
static extern int PathMakeUniqueName (
ref string pszUniqueName,
int cchMax,
string pszTemplate,
string pszLongPlate,
string pszDir
);

[DllImport("shell32.dll", EntryPoint="PathYetAnotherMakeUniqueName")]
static extern int PathYetAnotherMakeUniqueName (
ref string pszUniqueName,
string pszPath,
string pszShort,
string pszFileSpec
);

public void Test()
{
DirectoryInfo working = new DirectoryInfo(@"..\..\");

string buffer = new string(' ', MAX_PATH);
string folderSpec = working.FullName;
string name = "New Text Document.txt";

PathYetAnotherMakeUniqueName(ref buffer, folderSpec, null, name);

}

~ Paul
 
Hi Paul,
I'm having trouble getting the api PathYetAnotherMakeUniqueName to work.
Here is what I have so far. It is not working. What am i missing?

Use a StringBuilder for the first argument:
[DllImport("shell32.dll", EntryPoint="PathMakeUniqueName")]
static extern int PathMakeUniqueName (

StringBuilder pszUniqueName,
int cchMax,
string pszTemplate,
string pszLongPlate,
string pszDir
);


StringBuffer buffer = new StringBuffer(MAX_PATH);
...
PathYetAnotherMakeUniqueName(buffer, folderSpec, null, name);

bye
Rob
 
Hi,

Using StringBuilder allows the call to return correctly but the value is not
correct. It returns just the path and not the file name. Any ideas?

StringBuilder buffer = new StringBuilder(MAX_PATH);
PathYetAnotherMakeUniqueName(buffer, "D:\", null, "File.txt");

The value of buffer after call is just "D:\"

thanks,
~ Paul


Robert Jordan said:
Hi Paul,
I'm having trouble getting the api PathYetAnotherMakeUniqueName to work.
Here is what I have so far. It is not working. What am i missing?

Use a StringBuilder for the first argument:
[DllImport("shell32.dll", EntryPoint="PathMakeUniqueName")]
static extern int PathMakeUniqueName (

StringBuilder pszUniqueName,
int cchMax,
string pszTemplate,
string pszLongPlate,
string pszDir
);


StringBuffer buffer = new StringBuffer(MAX_PATH);
...
PathYetAnotherMakeUniqueName(buffer, folderSpec, null, name);

bye
Rob
 
Hi Paul,
Using StringBuilder allows the call to return correctly but the value is not
correct. It returns just the path and not the file name. Any ideas?

StringBuilder buffer = new StringBuilder(MAX_PATH);
PathYetAnotherMakeUniqueName(buffer, "D:\", null, "File.txt");

The value of buffer after call is just "D:\"

Please post the unmanaged declaration.

bye
Rob
 
Here is the code i'm testing with ...

const int MAX_PATH = 260;

[DllImport("shell32.dll", EntryPoint="PathYetAnotherMakeUniqueName")]
static extern int PathYetAnotherMakeUniqueName (
StringBuilder pszUniqueName,
string pszPath,
string pszShort,
string pszFileSpec);

public void Test()
{
DirectoryInfo working = new DirectoryInfo(@"..\..\");

StringBuilder buffer = new StringBuilder(MAX_PATH);
string folderSpec = @"D:\New Text Document.txt";
string fileSpec = "New Text Document.txt";

int result = PathYetAnotherMakeUniqueName(buffer, folderSpec, null,
fileSpec);

Debug.WriteLine(buffer.ToString());
}

I've read through the documentation a little more and it said that the
filename had to be included in the path. I did so but it is still not
working. Now, it just outputs the filename again. It does not give me a
unique name.

thanks for your help,
Paul
 
Interesting. I wonder what trick it takes to get it to work. I've tried
PathMakeUniqueName too and it doesn't seem to work either.

thanks
Paul
 
What do you mean it does not work from a c++ app? what error you get?

I made a simple c++ code, and it works for me.
///------------------------------------------------
#define UNICODE
#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <shlobj.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
DWORD lErr;
WCHAR oStr[MAX_PATH] = L"";
WCHAR p1[] = L"c:\\InoSetRTThread.log";
WCHAR pd[] = L"longfilename.log";

BOOL bRet = PathYetAnotherMakeUniqueName(oStr, p1,NULL, pd);

if( !bRet)
{
lErr = GetLastError();
char buf[32];
itoa(lErr,buf,16);
OutputDebugStringA(buf);
}
else
OutputDebugStringW(oStr);

return 0;
}
// eof

Best regards,
Rhett Gong [MSFT]
Microsoft Online Partner Support

This posting is provided "AS IS" with no warranties, and confers no rights.
Please reply to newsgroups only. Thanks.
 
Hi Rhett,
What do you mean it does not work from a c++ app? what error you get?

No errors. I simply don't understand what the function is supposed
to do. I just wanted to tell the OP there is no Interop related problem.

bye
Rob
 
Hi,

I was able to get the c++ version to work. I followed that exact same
syntax converted to c# and the c# version doesn't work. It simply gives
back the file name, even if it exits in the target directory.

Using c++ code provided, the output is "c:\longfilename (2).log". The
output of the c# version is "longfilename.log". There must be some Interop
issue. Anyone have any other ideas as to what to try?

thanks
Paul
 
The function is used to create a unique filename based on an existing
filename in the same path.
If you put a string in pszFileSpec, the output will base on the
pszFileSpec. But if you pass NULL in pszFileSpec , a unique filename is
created based on the existing filename.
eg. I put "c:\\InoSetRTThread.log" in pszPath and pass "longfilename.log"
in pszFileSpec then the output should be "longfilename.log" if there is no
file exist in the path with the same filename. Otherwise "longfilename
(2).log" will be generated.


Best regards,
Rhett Gong [MSFT]
Microsoft Online Partner Support

This posting is provided "AS IS" with no warranties, and confers no rights.
Please reply to newsgroups only. Thanks.
 
I was able to figure out the problem. It was an Interop issue. You simple
have to add CharSet=CharSet.Unicode to the DllImport attribute.

[DllImport("shell32.dll", EntryPoint="PathYetAnotherMakeUniqueName",
CharSet=CharSet.Unicode)]
internal static extern bool PathYetAnotherMakeUniqueName (
StringBuilder pszUniqueName,
string pszPath,
string pszShort,
string pszFileSpec );

After making this change, it works as expected.

thanks for the help,
Paul

Paul Welter said:
Hi,

I was able to get the c++ version to work. I followed that exact same
syntax converted to c# and the c# version doesn't work. It simply gives
back the file name, even if it exits in the target directory.

Using c++ code provided, the output is "c:\longfilename (2).log". The
output of the c# version is "longfilename.log". There must be some
Interop issue. Anyone have any other ideas as to what to try?

thanks
Paul

Rhett Gong said:
What do you mean it does not work from a c++ app? what error you get?

I made a simple c++ code, and it works for me.
///------------------------------------------------
#define UNICODE
#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <shlobj.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
DWORD lErr;
WCHAR oStr[MAX_PATH] = L"";
WCHAR p1[] = L"c:\\InoSetRTThread.log";
WCHAR pd[] = L"longfilename.log";

BOOL bRet = PathYetAnotherMakeUniqueName(oStr, p1,NULL, pd);

if( !bRet)
{
lErr = GetLastError();
char buf[32];
itoa(lErr,buf,16);
OutputDebugStringA(buf);
}
else
OutputDebugStringW(oStr);

return 0;
}
// eof

Best regards,
Rhett Gong [MSFT]
Microsoft Online Partner Support

This posting is provided "AS IS" with no warranties, and confers no
rights.
Please reply to newsgroups only. Thanks.
 
Hi Paul.

It was nice to hear that you have had the problem resolved. Thanks for
sharing your experience with all the people here. If you have any
questions, please feel free to post them in the community.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
Back
Top