so I am new to the whole c++ windows API. I'm creating a simple dialogbox in which the user types in a directory into a textbox for a time file which has already been created. the program will then read the file and display the time in another edit control. Im having a few problems making the directory entered the parameter for CreateFile(). If I hard code the directory in, the program will work correctly. But I cant figure out how to take the textbox data and plug it into the CreateFile() function. if this doesn't make sense i can try an explain differently. Ive searched an can't seem to find anything.
Thanks
for example:
if the user types c:\test\time.txt into the text box I want "c:\test\time.txt" to be the put into CreateFile();
CHAR temp[20] = "";
HANDLE hFile;
GetDlgItemText(hDlg, IDC_TEXTIN, temp, 20);//IDC_TEXTIN is name of edit control
//open file
hFile = CreateFile(
temp,
GENERIC_READ | GENERIC_WRITE,
0, // no sharing
NULL, // no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL // no template
);
Related
Is there a way to determine with C+++ if any file is open in a given directory tree?
Cmd.exe knows instantly if I attempt to rename a folder and a file within that directory tree is currently open. I've used API Monitor to determine that cmd.exe uses NtOpenFile() followed by NtSetInformationFile with FileRenameInformation and that returns STATUS_ACCESS_DENIED when a file is open but I've not been able to determine what's happening at a lower level.
I'm trying to ensure no files are open before beginning a batch process without having to check each file individually as there could be hundreds of thousands of files in the directory tree.
Can anyone expand on this?
Thanks,
Steve Thresher.
You will have to check each file individually, I think. That said, this should do it:
HANDLE hFile = CreateFile
(my_filename, GENERIC_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
DWORD err = GetLastError ();
if (err == ERROR_SHARING_VIOLATION)
{
// File is already open
}
}
else
CloseHandle (hFile);
Note that dwShareMode is passed as 0, which prevents Windows opening the file if it is already opened elsewhere.
I am having an issue with my application as while reading a file that consists of Unicode characters too. As I am using the CreateFileA method to get the data but it doesn't get the Unicode characters properly for which I am facing a lot of issues. Also, I don't know the difference between CreateFileA and CreateFileW.
I'm sorry I couldn't able to share my code. I will share my that portion of code with you.
HANDLE systemFileHandle = INVALID_HANDLE_VALUE;
systemFileHandle = CreateFileA(Filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
char* inBuffer=new char[totalFileSize+2];
memset(inBuffer, 0, totalFileSize+2);
ReadFile(systemFileHandle, inBuffer, totalFileSize, &bytesRead, nullptr);
And, I am getting the results on inBuffer array be like : Fernw�rmestationSW Au�en.
Can't I get it the original way they are?
So can you please help me out with this. It can be very helpful.
CreateFileA takes an ANSI-based file name, while CreateFileW takes a Unicode-based file name. There's nothing to say about the content of the file, both will return a HANDLE to the file where you can then read/write Unicode content as needed.
I wrote a small program which frequently opens small, user text files and until now haven't encountered any problems with read/write access or any sorts of conflict. The files are selected in another piece of software which I have no control over, and are passed to me as a string.
When attempting to open a file from a mapped network drive I am getting a "The system cannot find the path specified" error (GetLastError() = 3).
The call is shown below, *iNCfileName = "z:\\Validation\\Sample Files\\1_1-4 120MM.CC", where Z: is a mapped folder on our domain.
iNCfile = CreateFile( iNCfileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if ( iNCfile == INVALID_HANDLE_VALUE )
{
string msg; // lots of better ways to get this printed ... but ...
dw = GetLastError();
msg = iNCfileName;
msg += ": ";
msg += _com_error(dw).ErrorMessage();
print_error(dw , (char*)msg.c_str() );
return 102;
}
The file opens from my program if I copy it to the local hard drive. It also opens in notepad from the mapped drive.
Could this be a problem between the "Z:\whatever.txt" mapped representation and the true file name (\mydomain\Validation\S....??)?
If so, how can I convert from one to the other in a programmatic way (assume I won't know the domain/share names ahead of time)?
If it makes any difference I use VS2010 and the application executes on a Win XP machine.
Related: my follow up question
I've encountered this before. When using a path like \\DOMAIN\PATH\FILE.TXT I had to first call WNetAddConnection2().
Here is my code (of course you can exclude the NULL members):
NETRESOURCE nr = {0}; //new structure for network resource
nr.dwType = RESOURCETYPE_ANY; //generic resource (any type allowed)
nr.lpLocalName = NULL; //does not use a device
nr.lpRemoteName = "\\\\DOMAIN\\PATH\\FOLDER"; //For me, this pointed to an account's documents folder, and from there I could use a subfolder
nr.lpProvider = NULL; //no provider
DWORD ret = WNetAddConnection2 (&nr, NULL, NULL, CONNECT_TEMPORARY); //add connection
Don't forget the header and library.
I just had the same issue; trying to create a file using API CreateFileW under a mapped drive ( Z:\folder ) did not worked; howerver, after researching this subject i tried to create the file using the real path ( \\Shared_computer_name\folder\ ) immediately worked successfully.
Now I have to work a function to retrieve the real name of a mapped drive, to use it when necessary... just found WNetGetUniversalName, have to make it to work.
Is there a simple way to open a file by its associated program in windows?
(like double clicking it in windows explorer but done automatically with my code)
For example, on computer A, "text.txt" will be opened in wordpad but on computer B it will be opened by Notepad++ because of the users file extension assignments.
I tried ShellExecute
ShellExecute(0, L"open", L"c:\\windows\\notepad.exe" ,L"c:\\outfile.txt" , 0 , SW_SHOW );
which works but if I omit the notepad.exe parameter weird things happen (a random explorer is shown).
You want to use the file to open as the file argument, not the parameter argument. No need to specify which program to use, ShellExecute will look it up for you.
ShellExecute(0, 0, L"c:\\outfile.txt", 0, 0 , SW_SHOW );
By leaving the verb as NULL (0) rather than L"open", you get the true default action for the file type - usually this is open but not always.
See Launching Applications:
ShellExecute(NULL, "open", L"c:\\outfile.txt", NULL, NULL, SW_SHOW);
On windows, a good memory hook is to think of all data-files being executable by the shell. You can also try it out in a command box, where you can just type a filename, and it will be opened up. Or, the other way around, every file in Windows can be opened, and the default opening-action for executable files is to execute them.
According to the MS Knowledge Base, ShellExecute should work (we do this in Delphi all the time):
ShellExecute(Handle, "Open", Filename, "", "C:\", SW_SHOWNORMAL)
A little more possibilities here:
If you want to open - for example - the file by default with Notepad++ (if installed), you could scan for it's registry key if it exists and where it is, (Usually HKLM\SOFTWARE\Wow6432Node\Notepad++ [tested Win7]) then take that path and open it.
std::wstring file = L"C:\\Outfile.txt";
if (NotepadPlusPlusExists()) //Open with Notepad++ or use an other program... (maybe your own ?)
{
std::wstring wsNPPPath = GetNotepadPlusPlusPath();
ShellExecuteW(HWND, L"open", wsNPPPath.c_str(), file.c_str(), NULL, SW_NORMAL);
}
else //Open with default associated program <---
ShellExecuteW(HWND, NULL, file.c_str(), NULL, NULL, SW_NORMAL);
If you want the user to be able to change the default program or select a program he/she wants to use, you may open the "Open with" dialog.
//std::wstring StringArgsW(const wchar_t *format, ...);
std::wstring wsCmdOpenWith = StringArgsW(L"C:\\Windows\\system32\\shell32.dll,OpenAs_RunDLL \"%s\"", file.c_str());
ShellExecuteW(HWND, L"open", L"C:\\Windows\\system32\\rundll32.exe", wsCmdOpenWith.c_str(), NULL, SW_NORMAL);
You can also open the file in explorer.
std::wstring wsCmdExplorer = StringArgsW(L"/select,\"%s\"", file.c_str());
ShellExecuteW(HWND, L"open", L"explorer.exe", wsCmdExplorer.c_str(), NULL, SW_NORMAL);
If lpFile specifies a document file, the flag is simply passed to the
associated application
So you need to substitute "c:\\windows\\notepad.exe" with the actual file you want to open and leave lpParameters null.
Maybe try start instead of open?
I need to read data added to the end of an executable from within that executable .
On win32 I have a problem that I cannot open the .exe for reading. I have tried CreateFile and std::ifstream.
Is there a way of specifying non-exclusive read access to a file that wasn't initially opened with sharing.
EDIT- Great thing about stackoverflow, you ask the wrong question and get the right answer.
Why not just use resources which are designed for this functionality. It won't be at the end, but it will be in the executable.
If you are adding to the .exe after it is built -- you don't have to add to the end, you can update resources on a built .exe
http://msdn.microsoft.com/en-us/library/ms648049(VS.85).aspx
We do this in one of our projects. What's the problem with it? If the EXE is running, then it's already held open for reading, and you can continue to open it read-only multiple times. I just checked our code, we just use:
HANDLE file=CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
This works without problem on all versions of 32- and 64-bit Windows to date.
I have no problem opening the executable image of a process using either of these statements:
FILE* f = fopen( fname, "rb");
hFile = CreateFile( fname, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
What's your code?