|
|
Hi,
My program can now uninstall itself with a "-u" argument; and it'd invoked by CP->Add/Remove Programs just fine.
My question is, what is the proper way to delete my uninstall app's file itself? I can't delete it because it's locked when i'm running the app.
My only thought is to use HKLM/Software/Microsoft/Windows/CurrentVersion/RunOnce, and a cmd entry to delete the file, but this isn't really very smart. Surely there's a better way? How does installshield do it?
Thanks
Jon
#include <beer.h>
|
|
|
|
|
There is an MSDN article somewhere about different ways of doing this... but I can't seem to find it at the moment...
But anyway - the way to do this consistently on all OSes (9X, NT, 2000, XP), without having to wait for a reboot, is to use a batch file.
Let's say you have an uninstaller called Uninstall.exe. At run-time, right before your uninstaller exits, it should create a batch file in a temp directory somewhere that tries to delete Uninstall.exe, and once it succeeds, deletes itself. Here's an example to get you started (this originally came from an MSDN article, but has been hacked up a little bit ).
Note, you'll want to clean this up, there is no error checking, and some paths/filenames are hard-coded.
<code>
void DeleteThyself()
{
TCHAR unstFileName[] = "Uninstall.exe";
TCHAR tempDir[MAX_PATH];
DWORD error = 0;
::GetTempPath(MAX_PATH, tempDir);
TCHAR batFileName[MAX_PATH];
_tcscpy(batFileName, tempDir);
_tcscat(batFileName, "UnstTmp.bat");
ofstream batchFile(batFileName);
batchFile << ":Repeat\n";
batchFile << "del \"" << unstFileName << "\"\n";
batchFile << "if exist \"" << unstFileName << "\" goto Repeat\n";
batchFile << "del \"" << batFileName << "\"\n";
batchFile.close();
STARTUPINFO si;
PROCESS_INFORMATION pi;
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
if(::CreateProcess(NULL, batFileName, NULL, NULL, FALSE, IDLE_PRIORITY_CLASS, NULL, tempDir, &si, &pi))
{
::SetThreadPriority(pi.hThread, THREAD_PRIORITY_IDLE);
return true;
}
}
Even a broken clock is right twice a day.
|
|
|
|
|
DeleteMe.CPP
Module name: DeleteMe.cpp
Written by: Jeffrey Richter
Description: Allows an EXEcutable file to delete itself
********************************************************************/
#include <windows.h>
#include <stdlib.h>
#include <tchar.h>
/////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE h, HINSTANCE b, LPSTR psz, int n) {
// Is this the Original EXE or the clone EXE?
// If the command-line 1 argument, this is the Original EXE
// If the command-line >1 argument, this is the clone EXE
if (__argc == 1) {
// Original EXE: Spawn clone EXE to delete this EXE
// Copy this EXEcutable image into the user's temp directory
TCHAR szPathOrig[_MAX_PATH], szPathClone[_MAX_PATH];
GetModuleFileName(NULL, szPathOrig, _MAX_PATH);
GetTempPath(_MAX_PATH, szPathClone);
GetTempFileName(szPathClone, __TEXT("Del"), 0, szPathClone);
CopyFile(szPathOrig, szPathClone, FALSE);
// Open the clone EXE using FILE_FLAG_DELETE_ON_CLOSE
HANDLE hfile = CreateFile(szPathClone, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
// Spawn the clone EXE passing it our EXE's process handle
// and the full path name to the Original EXE file.
TCHAR szCmdLine[512];
HANDLE hProcessOrig = OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId());
wsprintf(szCmdLine, __TEXT("%s %d \"%s\""), szPathClone, hProcessOrig, szPathOrig);
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
CloseHandle(hProcessOrig);
CloseHandle(hfile);
// This original process can now terminate.
} else {
// Clone EXE: When original EXE terminates, delete it
HANDLE hProcessOrig = (HANDLE) _ttoi(__targv[1]);
WaitForSingleObject(hProcessOrig, INFINITE);
CloseHandle(hProcessOrig);
DeleteFile(__targv[2]);
// Insert code here to remove the subdirectory too (if desired).
// The system will delete the clone EXE automatically
// because it was opened with FILE_FLAG_DELETE_ON_CLOSE
}
return(0);
}
I am seeking...
For what?
Why did you ask me for what? I don't know!
|
|
|
|
|
Code like this was shown in an MSDN article. I think it only works for 9X though.
Even a broken clock is right twice a day.
|
|
|
|
|
i want to make my mouse pointer not to move close to the top of my client area of a window.i should make it to stop below 20 pixels from the top of the client area.how to do it.
|
|
|
|
|
Take a look at the API function ClipCursor()
Roger Allen
Sonork 100.10016
I have a terminal disease. Its called life!
|
|
|
|
|
Yuck!
Why, O, Why ? do people still want to restrict the users ?
Max.
|
|
|
|
|
Hi,
I know that I can include in my resources, Bitmaps, Icons, even Metafiles or AVI files...
But... I need to include something... just pieces of text ( something like pages of text), I would like to include that on the resources ( to have it then inside my exe file), and load it from there into an CString object, is that possible ?
For me it would be easier to put that ASCCI formatted text into a resource entry, than having const strings and all that things...
How can I do that ?, thanks greetings
Braulio
|
|
|
|
|
I'm not sure about the maximum size of characters in the string table, but maybe you could use it for the purpose!
Then you can load it into a CString like:
CString rr;
rr.LoadString(IDS_STRING);
hope this helps
|
|
|
|
|
You can definitely do it, just insert the text file as custom give it a name. I don't know how you will load it in MFC but here is what I did for Win32:
static char *pText;
HGLOBAL hResource;
switch(message)
{
case WM_INITDIALOG:
hResource = LoadResource (hInst,
FindResource (hInst, TEXT ("README"), TEXT("TEXT")));
pText = (char *) LockResource(hResource);
return TRUE;
this is from a dialog of mine. The Resource was given a name of "README" and the custom resource type "TEXT"; Then all you have to do is find/load and lock. That's it. Hope this helped.
|
|
|
|
|
Just what I was looking for !, Thanks a lot !
So long
Braulio
|
|
|
|
|
Thanks for the tip !!!
Finally I decide to use Win32, to make an screen saver ( from the sample ballFusion).
Just two more questions, after using the Text ( in the resource), should I free that ? ( I've seen LockResource but donno if it's neccessary to make a call to free that).
And another question... How can I get the handle of the instance in my application, hInst doesn't work because the thing of the screen saver seems to be special, in MFC it was easy something like "AfxGetApp" or other Afx call.
Sorry... I'm novice in Win32.. without sugar ( MFC or ATL)
thanks for your help, greetings
Braulio
|
|
|
|
|
Well, to tell you the truth, I am just a novice myself. I just did these thing recently so I know about them...If you do not need the text resource anymore then you should call FreeResource. My book says that even if you don't call FreeResource then it will be freed when the program terminates but I think that it's always a good idea to get rid of them when you are done with them. I think you also found a memory leak in my program since I was loading the resource every time I started the dialog and wasn't freeing it so thanks! About the the handle of the instance, there are many ways. What I use a global HINSTANCE hInst for example. In WinMain I set hInst = hInstance but you must set the global handle hInst to hInstance before CreateWindow in WinMain or else it won't work. I also found that out a couple of weeks ago. Other ways are in WM_CREATE you can declare a local HINSTANCE hInst and set it to hInst = ((LPCREATESTRUCT) lParam)->hInstance. Yet another way is GetWindowLong(hwnd, GWL_HINSTANCE). This also straight out of Charles Petzold's Programming Windows, in my opinion a book that everyone should have. Taught me everything I know! Good luck with your program.
|
|
|
|
|
Thanks a lot !
All this will help me a lot. In my former Jo I had that Petzold book, I think it's quite quite good ( I used it when MFC was not so good and I had to do some API stuff ), but in my current job I don't have it what a pity !
Thanks for the info, greetings
Braulio
|
|
|
|
|
Hi,
I have written this code to paint the background while resizing.
BOOL FrameWnd::OnEraseBkgnd(CDC* pDC)
{
CRect the_clientRect;
GetClientRect(&the_clientRect);
BITMAP the_bmp;
GetObject(the_bkgnd,sizeof(the_bmp),&the_bmp);
HDC hMemdc=CreateCompatibleDC(pDC->m_hDC);
if(hMemdc)
{
HBITMAP hOldBmp=(HBITMAP)SelectObject(hMemdc,the_bkgnd);
if(hOldBmp)
{
StretchBlt(pDC->m_hDC,0,0,the_clientRect.Width(),the_clientRect.Height(),hMemdc,0,0,the_bmp.bmWidth,the_bmp.bmHeight,SRCCOPY);
SelectObject(hMemdc,hOldBmp);
DeleteDC(hMemdc);
DeleteObject(hOldBmp);
return TRUE;
}
else
DeleteDC(hMemdc);
}
return TRue;
}
It works fine.But it flickers a lot.
Is there anyway to stop this flickering?
Regards,
Neha
|
|
|
|
|
|
Thanks for the link. That's a really good, succinct explanation; much better than any of the others I've found.
Software Zen: delete this;
|
|
|
|
|
|
Disable repainting while resizing.;)
Try this @ home. (B&B)
|
|
|
|
|
Could you tell me how to do this, I assume you are talking about situation where you only see the border of the window being moved and once you resized the window is painted again. This I would also like to do, plus, the same thing for moving a window, just the outline of it, then redraw.
|
|
|
|
|
You must proper handle the messages. For instance while resizing disable background painting. ( a Flag, reset after END resizing)
Read the posting and link above from "Rickard Andersson"
Try this @ home. (B&B)
|
|
|
|
|
I tried all of the above yet with no luck. Should I be disabling the background painting in the WM_PAINT message of WM_SIZE? If so what is the code for this? Maybe some code helps:
Here's my paint message:
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rectClient);
// Set Text Attributes
SetTextColor(hdc, RGB(0, 0, 225));
SetBkMode(hdc, TRANSPARENT);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
// Draw the Text
DrawText(hdc, szHeading, strlen(szHeading), &rectClient, DT_TOP |
DT_CENTER);
// Draw Horizontal Line
MoveToEx(hdc, 0, 35, NULL);
LineTo(hdc, rectClient.right, 35);
// Draw Vertical Line
MoveToEx(hdc, rectClient.right / 2, 35, NULL);
LineTo(hdc, rectClient.right / 2, rectClient.bottom - 100);
MoveToEx(hdc, 0, rectClient.bottom - 100, NULL);
LineTo(hdc, rectClient.right, rectClient.bottom - 100);
EndPaint(hwnd, &ps);
return 0;
And here is my sizing and colorlistbox message
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
MoveWindow(hwndLocalList, 5, 70, (cxClient / 2) - 10, cyClient - 165, FALSE);
MoveWindow(hwndHostList, (cxClient / 2) + 5, 70, (cxClient / 2) - 10,
cyClient - 165, FALSE);
return 0;
case WM_CTLCOLORLISTBOX:
SetTextColor( (HDC) wParam, RGB(255, 255, 255));
SetBkColor( (HDC) wParam, crBlue);
SelectObject( (HDC) wParam, GetStockObject(SYSTEM_FIXED_FONT));
return (LRESULT) hBlueBrush;
their wndclass.style is CS_VREDRAW | CS_HDREDRAW
Do you see what is wrong with the code?
|
|
|
|
|
WH_JOURNALRECORD and WH_JOURNALPLAYBACK
I try to use SetWindowsHookEx() and use two Hook type
WH_JOURNALRECORD and WH_JOURNALPLAYBACK to make
a capture and playback mechanism.
while on WH_JOURNALRECORD ,I store every messages that
the hookproc received,
and On WH_JOURNALPLAYBACK
I feed the messages I stored previously.
It seems works now,but still have some problems
while playback those messages.
1. it has TIME DELAY phenomena.
2. it has some messages lost phenomena.
the lost messages seems depends on system loading..
sometimes won't lost,but some times do if repeat playback
those messages recorded only once.
could someone have been done works like I do..??
any comment will be appreciate..
|
|
|
|
|
I have a dialog window with a CWebBrowser2 control on it, which I use to display a simple HTML report and allow it to be printed. I want the fact it is a web browser control to be transparent to the user, and therefore want to stop the IE menu from appearing when they right click on the control. Does anyone know where I can find code or an explaination on how to do this? I don't have much experience with ActiveX controls, and don't understand the explaination given to someone a while back.
|
|
|
|
|