Jump to content

problem restarting


Cosmin3

Recommended Posts

@Cosmin3

That would sure help some people around here

I look forward to testing it ;-)

Ok :)

First version. Only for tests!

The code (compiled in Delphi 7):

program SetVM;

uses
Windows, SysUtils;


{$R *.res}

type
TMemoryStatusEx = packed record
dwLength: DWORD;
dwMemoryLoad: DWORD;
ullTotalPhys: Int64;
ullAvailPhys: Int64;
ullTotalPageFile: Int64;
ullAvailPageFile: Int64;
ullTotalVirtual: Int64;
ullAvailVirtual: Int64;
ullAvailExtendedVirtual: Int64;
end;

function GlobalMemoryStatusEx(var lpBuffer: TMemoryStatusEx): BOOL; stdcall; external kernel32;

var
MS: TMemoryStatusEx;
CurrStr, StrToChg: AnsiString;
hTemp: HKEY;
WinPath: array[0..MAX_PATH + 1] of char;
Result: Boolean;
FreeAv, TotalAv, VMSize, CurrVal: Int64;
p: Integer;
Buf: Pointer;
BufSize: Cardinal;
ValType: DWORD;
sr: TSearchRec;

begin
Result := False;
CurrVal := 0;
try
MS.dwLength := SizEof(TMemoryStatusEx);
GlobalMemoryStatusEx(MS);
if MS.ullTotalPhys < 134217728 then
VMSize := 201326592
else
VMSize := Round(1.5 * MS.ullTotalPhys);
WinPath[0] := #0;
if GetWindowsDirectory(WinPath, MAX_PATH) = 0 then
Exit;
if not GetDiskFreeSpaceEx(PChar(WinPath[0] + ':\'), FreeAv, TotalAv, nil) then
Exit;
if FreeAv = 0 then
Exit;
try
if RegOpenKeyEx(HKEY_LOCAL_MACHINE, PChar('SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management'), 0, KEY_READ, hTemp) = ERROR_SUCCESS then
begin
if RegQueryValueEx(hTemp, PChar('PagingFiles'), nil, @ValType, nil, @BufSize) = ERROR_SUCCESS then
begin
GetMem(Buf, BufSize);
try
if RegQueryValueEx(hTemp, PChar('PagingFiles'), nil, @ValType, Buf, @BufSize) = ERROR_SUCCESS then
if BufSize > 0 then
begin
CurrStr := PChar(Buf);
p := Pos(' ', CurrStr);
Delete(CurrStr, p, Length(CurrStr) - p + 1);
if CurrStr <> '' then
if CharLower(PChar(CurrStr[1])) = CharLower(PChar(WinPath[0])) then
begin
if FindFirst(CurrStr, faAnyFile, sr) = 0 then
CurrVal := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow);
FindClose(sr);
end;
end;
finally
FreeMem(Buf);
end;
end;
RegCloseKey(hTemp);
end;
except
end;
if (FreeAv + CurrVal) <= VMSize then
Exit;
StrToChg := WinPath[0] + ':\pagefile.sys ' + IntToStr(Round(VMSize / 1048576)) + ' ' + IntToStr(Round(VMSize / 1048576));
try
if RegCreateKeyEx(HKEY_LOCAL_MACHINE, PChar('SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management'), 0, nil, REG_OPTION_NON_VOLATILE, KEY_WRITE, nil, hTemp, nil) = ERROR_SUCCESS then
begin
Result := RegSetValueEx(hTemp, PChar('PagingFiles'), 0, REG_MULTI_SZ, PChar(StrToChg + #0#0), Length(StrToChg) + 2) = ERROR_SUCCESS;
RegCloseKey(hTemp);
end;
except
end;
finally
if not Result then
MessageBox(0, 'Unable to set Virtual Memory values automatically'#13#10'Please set them manually!', 'SetVM', MB_ICONERROR or MB_OK);
end;
end.

I attached the exe file. Just run it and if there is no error message restart Windows.

Remember to backup your registry first, just in case :rolleyes:

Anyway, on my computer works fine.

Later edit: I made 2 small changes:

- The VM size is no longer limited to 4 GB;

- The exe file is a little smaller (I removed Math Unit).

Unfortunatelly, for now, this program can be used in 64 bit operating system only when the size of Ram is < 4 GB.

It is a limitation of GlobalMemoryStatus function (from kernel32.dll) who can return a 32 bit value (4 GB - 1).

I will try to find a better function.

Later later edit: I solved also the problem with GlobalMemoryStatus: I used GlobalMemoryStatusEx. Microsoft says that it should work fine.

But I can't test it, because I have only 2 GB.

Oh, and I also made the code to get the size of the current virtual memory file on the system drive.

SetVM.zip

Edited by Cosmin3
Link to comment
Share on other sites


So, from what I see, you have set pagefile size to be constructed as physically available RAM x 1.5.

In numbers: I have 768MB, but 751 are usable (shared video card) So, 751x1.5=1126.5, and I got 1127.

Conclusion: Congrats! It worked for me

P.S. A small insight on how some other members do it; for example, cluberti has posted this http://www.cluberti.com/blog/2010/06/17/pagefile-vbs-for-vistawin7-systems-may-work-on-xp2003-not-tested/ in .vbs to be run with cscript.

Now, pagefile.sys is set by default to be created on the system drive (normally c:\), but I wonder if it could also be split on two drives, like I normally do it.

Link to comment
Share on other sites

So, from what I see, you have set pagefile size to be constructed as physically available RAM x 1.5.

In numbers: I have 768MB, but 751 are usable (shared video card) So, 751x1.5=1126.5, and I got 1127.

Conclusion: Congrats! It worked for me

You're welcome.

Now, pagefile.sys is set by default to be created on the system drive (normally c:\), but I wonder if it could also be split on two drives, like I normally do it.

When you say "two drives" you mean two physical drives or 2 logical drives (on the same physical drive)..?

Link to comment
Share on other sites

When you say "two drives" you mean two physical drives or 2 logical drives (on the same physical drive)..?

In my case, I have one primary partition on one HDD (apart from the system drive), but will it be any different if there are two separate HDDs? If more explanation is needed, I mainly divide pagefile.sys because of free space; a small amount (256MB, for example) on C:\ and the rest on D:\

Cheers

Edited by Sp0iLedBrAt
Link to comment
Share on other sites

In my case, I have one primary partition on one HDD (apart from the system drive), but will it be any different if there are two separate HDDs? If more explanation is needed, I mainly divide pagefile.sys because of free space; a small amount (256MB, for example) on C:\ and the rest on D:\

Cheers

For my program no, I asked only because having 2 or more pagefiles on the same physical drive is not good (slower access).

Ok, I'll let you choose a way to implement (configuration file or command line parameters) and the "syntax" to be used :D

It should be easy to understand and use...

Link to comment
Share on other sites

Version 2.0 :D


program SetVM;

uses
Windows, SysUtils, StrUtils;


{$R *.res}

type
TMemoryStatusEx = packed record
dwLength: DWORD;
dwMemoryLoad: DWORD;
ullTotalPhys: Int64;
ullAvailPhys: Int64;
ullTotalPageFile: Int64;
ullAvailPageFile: Int64;
ullTotalVirtual: Int64;
ullAvailVirtual: Int64;
ullAvailExtendedVirtual: Int64;
end;

type
TCurrVal = record
Drive: Char;
Size: Int64;
end;

function GlobalMemoryStatusEx(var lpBuffer: TMemoryStatusEx): BOOL; stdcall; external kernel32;

var
MS: TMemoryStatusEx;
CurrStr, StrToChg, IniName, s: AnsiString;
hTemp: HKEY;
WinPath: array[0..MAX_PATH + 1] of char;
Result: Boolean;
FreeAv, TotalAv, VMSize, CurrVal: Int64;
i, j, p, l, NrDefVal: Integer;
Buf: Pointer;
BufSize: Cardinal;
ValType: DWORD;
sr: TSearchRec;
CurrValA, FtValA: array of TCurrVal;
t: TextFile;

begin
Result := False;
try
try //tries to read the current configuration
if RegOpenKeyEx(HKEY_LOCAL_MACHINE, PChar('SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management'), 0, KEY_READ, hTemp) = ERROR_SUCCESS then
begin
if RegQueryValueEx(hTemp, PChar('PagingFiles'), nil, @ValType, nil, @BufSize) = ERROR_SUCCESS then //query buffer size
begin
GetMem(Buf, BufSize);
try
if RegQueryValueEx(hTemp, PChar('PagingFiles'), nil, @ValType, Buf, @BufSize) = ERROR_SUCCESS then
if BufSize > 0 then
begin
CurrStr := AnsiLowerCase(string(Buf));
SetLength(CurrValA, 0);
i := -1;
p := Pos('pagefile.sys', CurrStr);
while p > 0 do //recursive search for each pagefile
begin
Inc(i);
SetLength(CurrValA, i + 1);
CurrValA[i].Drive := CurrStr[p - 3];
//get the actual size of the pagefiles
if FindFirst(Copy(CurrStr, p - 3, 15), faAnyFile, sr) = 0 then
CurrValA[i].Size := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow);
FindClose(sr);
p := PosEx('pagefile.sys', CurrStr, p + 12);
end;
end;
finally
FreeMem(Buf);
end;
end;
RegCloseKey(hTemp);
end;
except
end;
StrToChg := '';
//get the Ram informations
MS.dwLength := SizEof(TMemoryStatusEx);
GlobalMemoryStatusEx(MS);
if MS.ullTotalPhys < 134217728 then // if RAM size is lower than 128 MB (most probably a reading bug)
VMSize := 201326592
else
VMSize := Round(1.5 * MS.ullTotalPhys);
IniName := Copy(ParamStr(0), 1, Length(ParamStr(0)) - 3) + 'ini';
if FileExists(IniName) then //if configuration file exists
begin
//reads the configuration file
AssignFile(t, IniName);
FileMode := 0;
i := -1;
NrDefVal := 0;
SetLength(FtValA, 0);
try
Reset(t);
while not Eof(t) do
begin
Readln(t, s);
if Pos('#', s) = 1 then
Continue;
l := Length(s);
if l > 2 then
if (s[1] in ['a'..'z']) or (s[1] in ['A'..'Z']) then
if s[2] = '=' then
begin
Inc(i);
SetLength(FtValA, i + 1);
if s[1] in ['a'..'z'] then
FtValA[i].Drive := s[1]
else
FtValA[i].Drive := Char(Byte(s[1]) + 32);
if s[3] = '*' then
begin
FtValA[i].Size := -1;
Inc(NrDefVal);
end
else
FtValA[i].Size := StrToInt64def(Copy(s, 3, l - 2), 0) * 1048576;
end;
end;
except
end;
CloseFile(t);
if i = -1 then
Exit;
if NrDefVal > 0 then //if the number of * is at least 1
begin
for i := 0 to High(FtValA) do
if FtValA[i].Size <> -1 then
VMSize := VMSize - FtValA[i].Size; //calculate the default size
for i := 0 to High(FtValA) do
begin
//assignes default values when * is used
if FtValA[i].Size = -1 then
FtValA[i].Size := Round(VMSize / NrDefVal);
//if assigned value is 0 or negative then it's a problem
if Round(FtValA[i].Size / 1048576) < 1 then
Exit;
end;
end;
for i := 0 to High(FtValA) do //for each drive
begin
if not GetDiskFreeSpaceEx(PChar(FtValA[i].Drive + ':\'), FreeAv, TotalAv, nil) then //can't read free disk space (drive/OS error)
Exit;
if FreeAv = 0 then //no free space on that drive; most probably a drive error or a read-only one...
Exit;
j := 0;
while j < Length(CurrValA) do //search for records about current pagefile on that drive
begin
if CurrValA[j].Drive = FtValA[i].Drive then
Break;
Inc(j);
end;
//tests if the new pagefile fits
if j < Length(CurrValA) then
begin
if (FreeAv + CurrValA[i].Size) <= FtValA[i].Size then
Exit;
end
else
if FreeAv <= FtValA[i].Size then
Exit;
//text to change in registry
StrToChg := StrToChg + FtValA[i].Drive + ':\pagefile.sys ' + IntToStr(Round(FtValA[i].Size / 1048576)) + ' ' + IntToStr(Round(FtValA[i].Size / 1048576)) + #0;
end;
Delete(StrToChg, Length(StrToChg), 1); //delete unused #0 at the end
end
else
begin //no configuration found so it sets one file on Windows drive
WinPath[0] := #0;
if GetWindowsDirectory(WinPath, MAX_PATH) = 0 then //can't read the name of Windows folder (drive/OS error)
Exit;
if not GetDiskFreeSpaceEx(PChar(WinPath[0] + ':\'), FreeAv, TotalAv, nil) then //can't read free disk space (drive/OS error)
Exit;
if FreeAv = 0 then //no free space on that drive; most probably a drive error or a read-only one...
Exit;
WinPath[0] := Char(CharLower(PChar(WinPath[0])));
i := 0;
CurrVal := 0;
while i < Length(CurrValA) do //search for records about current pagefile on Windows drive
begin
if CurrValA[i].Drive = WinPath[0] then
begin
CurrVal := CurrValA[i].Size;
Break;
end;
Inc(i);
end;
//tests if the new pagefile fits
if (FreeAv + CurrVal) <= VMSize then
Exit;
//text to change in registry
StrToChg := WinPath[0] + ':\pagefile.sys ' + IntToStr(Round(VMSize / 1048576)) + ' ' + IntToStr(Round(VMSize / 1048576));
end;

//tries to write in registry
try
if RegCreateKeyEx(HKEY_LOCAL_MACHINE, PChar('SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management'), 0, nil, REG_OPTION_NON_VOLATILE, KEY_WRITE, nil, hTemp, nil) = ERROR_SUCCESS then
begin
Result := RegSetValueEx(hTemp, PChar('PagingFiles'), 0, REG_MULTI_SZ, PChar(StrToChg + #0#0), Length(StrToChg) + 2) = ERROR_SUCCESS;
RegCloseKey(hTemp);
end;
except
end;
finally
if not Result then //some error happened so it shows a message
MessageBox(0, 'Unable to set Virtual Memory values automatically'#13#10'Please set them manually!', 'SetVM', MB_ICONERROR or MB_OK);
end;
end.

Configuration is set in SetVM.ini:

C=300
D=*

The user can set the size directly (in MB) or * for the default value.

If the ini file is missing it sets like in previous version.

SetVM.zip

Edited by Cosmin3
Link to comment
Share on other sites

You were right, it just can't get any simpler that this :yes:

All we need now is someone with more understanding of the XP install process to tell us if it can be run through RunOnce.

Keep up the good work :thumbup

I tested it...

I made an $OEM$\$$\Temp\ folder on XP installation CD and I copied the files in it.

At Unattended >> RunOnce section in nlite I added %windir%\Temp\SetVM.exe.

During installation I didn't see any error message.

It seems it worked:

capturefa.png

Link to comment
Share on other sites

Cool!

I was thinking of putting in a batch file and doing something like

REM Setting virtual memory
start /wait %source%$OEM$\VM\setVM.exe

because I was interested whether it would work if it was run before the actual first logon.

I'll test this too and get back.

Cheers

Link to comment
Share on other sites

Cool!

I was thinking of putting in a batch file and doing something like

REM Setting virtual memory
start /wait %source%$OEM$\VM\setVM.exe

because I was interested whether it would work if it was run before the actual first logon.

I'll test this too and get back.

Cheers

I tried myself with "%source%" a few weeks ago (for other program) but this environment variable isn't recognized after the installation is over.

Anyway, even if it works when installing from CD, surely it won't work when installing from USB stick.

Link to comment
Share on other sites

I tried myself with "%source%" a few weeks ago (for other program) but this environment variable isn't recognized after the installation is over.

Anyway, even if it works when installing from CD, surely it won't work when installing from USB stick.

Cosmin3, please see nLite.cmd (compressed into NLITE.CM_) for how nLite determines %Source%. An even more transparent way is common around here that I copied:

for %%i in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%i:\sources\install.wim set CDROM=%%i:

Just change the file name to something unique on the drive you are interesting on getting the letter. Enjoy, John.

Link to comment
Share on other sites

Cosmin3, please see nLite.cmd (compressed into NLITE.CM_) for how nLite determines %Source%.

I found it only as "c:\WINDOWS\system32\nlite.cmd". I couldn't find it in installation files as nlite.cm_ (or anywhere else for that matter).

I kept only the first line:

for /f "tokens=3" %%i IN ('reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup /v "SourcePath" ^| findstr "REG_SZ"') do set SOURCE=%%i

It gives me a temporary %source% variable (set on my system as "E:"). But soon as I close cmd window, it's gone.

Anyway it doesn't work with USB stick installation because, obviously, the CD ain't there...

An even more transparent way is common around here that I copied:

for %%i in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%i:\sources\install.wim set CDROM=%%i:

Just change the file name to something unique on the drive you are interesting on getting the letter. Enjoy, John.

I will use it like this:

for %%i in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%i:\SetVM\SetVM.exe %%i:\SetVM\SetVM.exe

But the problem is that I have to use a *.cmd file for this command, which I have to place it in a $OEM$ folder so I can run it. This is what I tried to avoid in the first place...

But thank you.

Edited by Cosmin3
Link to comment
Share on other sites

I got it to work from RunOnce! :thumbup

The biggest problem I had was to create a partition and name it D:\ in VirtualBox, which I did by splitting the VHD, formatting one partition into NTFS (Quick) and then hitting restart. The procedure began again. This time I formatted the second partition (which was already in FAT32) into NTFS (Quick) and the newly formatted partition took drive letter C:\ when I installed on it. The recommended amount was 388MB, and I got 389MB.

This is a snapshot of the end result

post-236786-050529700 1286201901_thumb.j

Edited by Sp0iLedBrAt
Link to comment
Share on other sites

I got it to work from RunOnce! :thumbup

The biggest problem I had was to create a partition and name it D:\ in VirtualBox, which I did by splitting the VHD, formatting one partition into NTFS (Quick) and then hitting restart. The procedure began again. This time I formatted the second partition (which was already in FAT32) into NTFS (Quick) and the newly formatted partition took drive letter C:\ when I installed on it. The recommended amount was 388MB, and I got 389MB.

This is a snapshot of the end result

post-236786-050529700 1286201901_thumb.j

Glad to hear this :)

Link to comment
Share on other sites

  • 4 weeks later...

I'm back :D

I have set Automatic Updates to "Notify me but don't automatically download or install them".

When I install, in oobe is asking me to enable Automatic updates, which is pointless.

How can I set it not to ask this, but keeping oobe...?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...