How to set an environment variable by setting it in the registry

June 5, 2009 by slightlybehindthecurve

It’s easy to do a “getenv” , but you’d be surprised at how hard it is to set an environment variable.
Sorry, I’m not going to take the time to write here what I learned from some excellent explanations found at codeguru and elsewhere, but I’ll try to post those links at the last.
Basically:
1) set the current user\environment\yourstring=value in the registry
2) send a windows refresh message (this doesn’t communicate with whatever command prompts you may already have, but it will work for the calling process)
3) whatever new command prompt or process will use your new setting


LRESULT CMainDlg::OnSetMyEnvironmentValue(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CString sNetId;
GetDlgItem(IDC_NETID).GetWindowTextA(sNetId);

Handle_SetReg(sNetId);
Handle_RefreshEnvironment();
return Handle_SetEnv(sNetId);
return 0;
}

int CMainDlg::Handle_SetEnv(CString sNetId)
{
//MessageBox (sNetId, "netid", 0) ; //sNetId.GetBuffer()

// set env variable
int iRet = 0;
iRet = SetEnvironmentVariable("netid", sNetId.GetBuffer() );

if( iRet <=0 )
{
GetLastError();
return -1;
}
return 0;

}

int CMainDlg::Handle_SetReg(CString sNetId)
{
CString subKey = "Environment";
HKEY hKey;
char *m_tmpChar = new char[100];

if (RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_SET_VALUE, &hKey))
{
MessageBox("Error opening the key");
RegCreateKey(HKEY_CURRENT_USER, subKey,&hKey);
}

if ( RegSetValueEx(hKey, "netid" , NULL , REG_SZ, (unsigned char*)sNetId.GetBuffer() ,sNetId.GetLength() +1) )
MessageBox("Error setting the value");
RegCloseKey(hKey);

return 0;
}

// http://wiki.answers.com/Q/How_do_you_set_registry_entry_as_environment_variable
int CMainDlg::Handle_RefreshEnvironment()
{
DWORD_PTR dwReturnValue;

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
(LPARAM) "Environment", SMTO_ABORTIFHUNG,
500, &dwReturnValue);
return dwReturnValue;
}

Here were some helpful links:
reading:
basics
http://www.codeguru.com/forum/showpost.php?p=1171365&postcount=7

REGISTRY
HKEY_CURRENT_USER\Environment
HKEY_CURRENT_USER\VolatileEnvironment
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
http://vlaurie.com/computers2/Articles/environment.htm
VISTA http://vistaonwindows.com/environment_variables.html

registry
http://www.codeguru.com/cpp/w-p/system/registry/print.php/c5793

6/4/09
helpful
http://wiki.answers.com/Q/How_do_you_set_registry_entry_as_environment_variable

looks like broadcasting the wm_settingchange won’t talk to cmd prompts
http://coding.derkeiler.com/Archive/Python/comp.lang.python/2006-03/msg05284.html

search all tables for a string

June 5, 2009 by slightlybehindthecurve

I needed to search the ‘description’ field of every table in my database for a string.
To do that, I generated a column of search commands.
Then I copied those search commands into a new query window in sql server enterprise manager and executed them. I could see which tables contained the string I was looking for.

Here is the sql to generate the column of commands. A trick is to concatenate the literal single quote string.

**********************************************
SEARCH all tables , ALL COLUMNS NAMED ‘DESCRIPTION’ FOR RECORDS CONTAINING A KEY WORD
*******************

select (‘Select ‘ + char(39) + table_name + char(39) + ‘ as TableName ,* from ‘ + table_name + ‘ where [description] like ‘ + char(39) + ‘%Back Flow%’ + char(39) + ‘ ‘ ) as copyandexecute , column_name from INFORMATION_SCHEMA.columns
where column_name = ‘Description’
order by column_name

search all stored procedures for a string

June 5, 2009 by slightlybehindthecurve

Search all stored procedures that contain some text

select specific_name , Routine_Definition from INFORMATION_SCHEMA.ROUTINES
where Routine_Definition like ‘%tblRatingSectionItemAttribute%’
– runs into a limit on string length

THIS WORKED
SELECT OBJECT_NAME(id) , [text]
FROM syscomments
WHERE [text] LIKE ‘%Back Flow%’
AND OBJECTPROPERTY(id, ‘IsProcedure’) = 1
GROUP BY OBJECT_NAME(id) , [text]

how to create a modeless (non-modal) dialog in WTL (ATL , C++)

May 25, 2009 by slightlybehindthecurve

modeless dialog:
thanks to http://www.sowbug.org/mt/2004/01/modeless-dialogs.html#more

1) in MainDlg.h , a class global for the dialog (otherwise it will be created and destroyed in
the same subroutine and throw an exception)
CBigFocusDlg dlgBigFocus;

2) Create the modeless dialog in response to a button click in the main dialog

// **************************************
LRESULT CMainDlg::OnBnClickedShow_Big_Focus_Dlg(WORD /*wNotifyCode*/, WORD

/*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// if it already exists, then bring it to top and return
if ( dlgBigFocus ) {
::BringWindowToTop(dlgBigFocus.m_hWnd);
return 0;
}

// MODELESS DIALOG
// http://www.sowbug.org/mt/2004/01/modeless-dialogs.html#more

dlgBigFocus.Create(NULL );
dlgBigFocus.CenterWindow(this->m_hWnd);
dlgBigFocus.ShowWindow(SW_SHOWNORMAL);

return 0;
}

// ******************************************************************************
// how to close the dialog:

LRESULT CBigFocusDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// center the dialog on the screen
CenterWindow();

return TRUE;
}

LRESULT CBigFocusDlg::OnCloseCmd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
this->DestroyWindow();
return 0;
}

// **************************************
LRESULT CBigFocusDlg::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
this->DestroyWindow();
return 0;
}

html checkbox in 1.1 datagrid bound to data

May 20, 2009 by slightlybehindthecurve

If you’re used to .net server controls, you’ll probably want to set the checked property on a checkbox control to true. Well that won’t work.
It displays either checked or not checked depending on whether the string checked is one of its attributes.

Here is a way to make it happen in a templated column in a datagrid in old-school .net 1.1:


1) the templated column

<input type="checkbox" onclick="ajaxws_OnCheckBoxChanged(this)"
id='chkgrid$tDownloads$isHomeUse$sdKy$'

>

a) the line must be either the
string "checked" (without the quotes), or nothing at all. You cannot set checked=1, or checked=true, etc.
b) NOTE - we don't have quotes around the stuff, so you can not edit the page in design mode

2) therefore we convert the boolean to a string with a case statement when we do the database query:
(also take care for isNull)
CASE isNull(isHomeUse, 0)
WHEN 1 THEN 'checked'
ELSE ''
END AS isHomeUse

Note: I’m not so good at getting the Eval syntax to work. I don’t like returning an html string from my sql query, but at least this way works. I’d be interested in hearing from someone who can improve on this.
But I won’t hold my breath, since this code seems so 2002.

function to return the current value and id of all controls

May 14, 2009 by slightlybehindthecurve

I ended up not using this yet, but it returns a dictionary collection of all controls contained in a page, for example, and their current value. This includes textboxes, dropdowns, radios, and checkboxes.
I usually credit the original source for functions like these, but I lost where the recursive sub came from

' **************************************************************************
' purpose: function to call the recursive sub and then return the dictionary containing the results
Public Shared Function get_all_controls(ByVal container As Control) As Hashtable
htControls.Clear()
Dim strTemp As String = container.ID & " " & container.ClientID
strTemp = strTemp + container.UniqueID + " " + container.Page.Title
Diagnostics.Debug.Print(strTemp)
get_all_controls_recursive(container)
Return htControls
End Function

' **************************************************************************
' recursive sub to list all controls in a container
Public Shared Sub get_all_controls_recursive(ByVal container As Control)
Dim strTemp As String
Dim bFound As Boolean = False

For Each ctl As Control In container.Controls

bFound = False

strTemp = ctl.ID

If (Not bFound) Then
Dim txt As TextBox = TryCast(ctl, TextBox)
If (Not IsNothing(txt)) Then
htControls.Add(txt.ID, txt.Text)
bFound = True
End If
End If

If (Not bFound) Then
Dim ddl As DropDownList = TryCast(ctl, DropDownList)
If (Not IsNothing(ddl)) Then
htControls.Add(ddl.ID, ddl.Text)
bFound = True
End If
End If

If (Not bFound) Then
Dim chk As CheckBox = TryCast(ctl, CheckBox)
If (Not IsNothing(chk)) Then
htControls.Add(chk.ID, chk.Checked.ToString())
bFound = True
End If
End If

If (Not bFound) Then
Dim rdio As RadioButton = TryCast(ctl, RadioButton)
If (Not IsNothing(rdio)) Then
htControls.Add(rdio.ID, rdio.Checked.ToString())
bFound = True
End If
End If

If (ctl.Controls.Count > 0) Then get_all_controls_recursive(ctl)

Next

End Sub

get the current page name

May 14, 2009 by slightlybehindthecurve

I wanted to get the page name of the current *.aspx page that I was in. This is what I did (not rocket science, admittedly)

' *****************************************************************************
' purpose - return the aspx page name
Public Shared Function GetCurrentPageName() As String
Dim strRet As String = ""
'Return System.Web.HttpContext.Current.Request.Url.ToString
Dim sBasePath As String = System.Web.HttpContext.Current.Server.MapPath("")
Dim sFullPath As String = System.Web.HttpContext.Current.Request.ServerVariables("PATH_TRANSLATED")
sBasePath = sBasePath.ToLower() + "\"
sFullPath = sFullPath.ToLower()
strRet = sFullPath.Replace(sBasePath, "")
Return strRet
End Function

change the style at the server

May 14, 2009 by slightlybehindthecurve

I made a user control, and I wanted to add a ctl_Width property and apply the value to all the contained sub-controls.
But setting the “Width” property of each did not work – I had to change the style of each. So I made some functions to help me in setting the style attribute of each of the sub controls contained in my user control. Here are the functions:

' ------------------------------------------------------------------------------
' purpose - set some style at the server side
' how to call: iRet = SetStyleValue(ddlCombo, "width", sWidth, strError)
' ref: http://codebetter.com/blogs/brendan.tompkins/archive/2003/10/23/2827.aspx
Public Shared Function SetStyleValue(ByVal o As System.Web.UI.WebControls.WebControl, ByVal sKey As String, ByVal sVal As String, Optional ByRef strError As String = "") As Integer
Try
o.Style.Add(sKey, sVal)
Return 1
Catch ex As Exception
strError = ex.Message
Return -666
End Try
End Function

' *********************************************************************
' purpose - get the current style string for the control
' ref:http://codebetter.com/blogs/brendan.tompkins/archive/2003/10/23/2827.aspx
' how to call:
Public Shared Function GetStyleString(ByVal o As System.Web.UI.WebControls.WebControl) As String
Dim strStyle As String = ""
Try
Dim S As System.Web.UI.CssStyleCollection = o.Style
For Each key As String In S.Keys
strStyle += key + ":" + S(key) + ";"
Next
Catch ex As Exception
strStyle = "ERROR"
End Try
Return strStyle
End Function

count all recently updated time-sensitive records in an entire database

April 8, 2009 by slightlybehindthecurve


-- purpose - see if this database is being updated
-- use a set of queries on datetime fields.
-- Make the queries dynamic, and pass in the table and column names.
-- collate results into a temp table and then display all together
declare @t_name varchar(50)
declare @c_name varchar(50)
declare @query_base varchar(250)
set @query_base = 'select {QQQTABLE} as [TableName], count(*) as CountRecentUpdates from QQQTABLE where

QQQCOLUMN > dateadd(d,-1,getdate() )'
declare @query varchar(500)
declare @TempTableInsert varchar(80)
set @TempTableInsert = ' insert into #MyTempTable ([TableName] , [CountRecentUpdates] ) '

CREATE TABLE #MyTempTable ([TableName] varchar(50), [CountRecentUpdates] varchar(50) )

declare ci cursor for
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE (DATA_TYPE = 'datetime') AND (NOT (COLUMN_DEFAULT IS NULL))

open ci

fetch next from ci into
@t_name,
@c_name

WHILE @@FETCH_STATUS = 0

BEGIN

--print @t_name + ' ' + @c_name

set @query = replace(@query_base,'QQQTABLE', @t_name)
set @query = replace(@query ,'QQQCOLUMN', @c_name)
set @query = replace(@query ,'{' , char(39) )
set @query = replace(@query ,'}' , char(39) )
set @query = @TempTableInsert + @query
--print @query
EXECUTE(@query)
-- *************************************************************
-- RE-LOAD THE CURSOR
fetch next from ci into
@t_name,
@c_name

end
close ci
deallocate ci

select * from #MyTempTable
drop table #MyTempTable

/*
reference query
SELECT TABLE_NAME, COLUMN_NAME, IS_NULLABLE, DATA_TYPE, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE (DATA_TYPE = 'datetime') AND (NOT (COLUMN_DEFAULT IS NULL))

*/

The output looks like this:

TableName CountRecentUpdates
Exceptions 0
Results 232
Links 0
Results_Unstructured 0
Debugging 3290
AppStatus 0
OutageLog 0
Events 1008
StatusLog 0
Queries 3

recursive stored procedure

March 11, 2009 by slightlybehindthecurve

The business purpose of this stored procedure is to permit a project to contain a sub-project. Because each sub-project could again contain other projects, it looked like I could potentiall get infinite loops in my logic. Therefore I wanted to prevent loop backs in my chains of projects.

The recursive stored procedure was able to walk up the chain of containing projects, and could be used to prevent a project from being inserted twice in the same chain.

There were a few tricks involved, and since it’s been about a month since I worked on this, I’m not sure I can remember all that, and for the time being will simply post the create scripts and hope that they are not too implementation specific and perhaps useful to somebody.

There are two important tables – a Projects table, where each project has an integer projectkey, and then a ProjectsOfProjects table, where each entry has a parent key, a child key, and a grandparent key. If you walk up a chain of records, at some point the grandparent key is null, and that is the end of the chain.

/****** Object: StoredProcedure [dbo].[ProjectAncestors] Script Date: 03/11/2009 17:14:20 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
/*
-- purpose: can we add this child to the specified parent?
-- return false if no, true if yes,
-- returns all the ancestors by recursively calling itself
-- until the last record has a null for the parent key
-- HOW TO RUN:
-- exec ProjectAncestors 40, 30 , 8 , 1
-- Child key - the current project
-- Parent key - the parent project
-- Parent_ikey - the field in the ikey'th record in the ProjectsOfProjects table where the parent's parent is defined
-- (this is the trick that enables us to "walk up" the table and get all the ancestors
SAMPLES: (we had already set up the ProjectsOfProjects table so that there were some children and parents defined)
exec ProjectsOfProjects_ADD 50 , 30, 8 , 1
NOTE - the first execution of [ProjectAncestors] has to have @start=1

declare @OkToInsert bit
exec @OkToInsert = ProjectAncestors 60,30,8,1
print @OkToInsert

exec ProjectAncestors 40, 30 , 8, 1
*/
-- =============================================
CREATE PROCEDURE [dbo].[ProjectAncestors]
@childkey int,
@parentkey int,
@parent_ikey int,
@start int ,
@returncode int OUTPUT

AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
set @returncode = -99

print '******* run [ProjectAncestors] NestLevel=' + convert(varchar(10), @@nestlevel)

declare @Kount int

-- 1) if temp table doesn't exist, then create it
if @start = 1
begin
IF OBJECT_ID('tempdb..#ProjectAncestors') IS NOT NULL drop table #ProjectAncestors

-- set up the table to hold the chain of ancestors
CREATE TABLE #ProjectAncestors (parentkey INT)
-- set up the table to hold the global variable
CREATE TABLE #GlobalVars (childkey INT)
INSERT INTO #GlobalVars (childkey ) VALUES (@childkey )

print ' set the original childkey ' + convert(varchar(10), @childkey)
end

-- 2) go ahead and insert the parameter
INSERT INTO #ProjectAncestors (parentkey ) VALUES (@parentkey )

-- 3) check for the end - when the parent_ikey is null, there are no more relationships defined in the ProjectOfProjects table
if @parent_ikey is NULL
begin
-- a. is it valid to make the relationship? if the desired child was already in the list of ancestors, then it is NOT
-- BUT - remember, this is a recursive procedure, the child key is changing each time we call it. We need to check
-- on the original child key
declare @original_childkey int
select @original_childkey=childkey from #GlobalVars
print ' test the @original_childkey=' + convert(varchar(12),@original_childkey)
select @Kount = count(*) from #ProjectAncestors where parentkey=@original_childkey

-- return the result set
select * from #ProjectAncestors

drop table #ProjectAncestors

print '[ProjectAncestors] just before return @Kount=' + convert(varchar(10),@Kount )
if @Kount > 0
begin
print ' return 0 from [ProjectAncestors]'
print ' the input child record ' + convert(varchar(25), @original_childkey)
print ' was found in the list of ancestors, and therefore cannot be added'
set @returncode = 0
print ' @returncode in [ProjectAncestors]:' + convert(varchar(10),@returncode )
IF OBJECT_ID('tempdb..#ReturnCode') IS NOT NULL
begin
insert into #ReturnCode (returncode) values (@ReturnCode)
end

return 0
end
else
begin
print ' return 1 from [ProjectAncestors]'
print ' the input child record ' + convert(varchar(25), @original_childkey)
print ' was NOT found in the list of ancestors, and therefore CAN be added'
set @returncode = 1
print ' @returncode in [ProjectAncestors]:' + convert(varchar(10),@returncode )
IF OBJECT_ID('tempdb..#ReturnCode') IS NOT NULL
begin
insert into #ReturnCode (returncode) values (@ReturnCode)
end
return 1
end

end

else
begin
print '@parent_ikey is NOT NULL ' + convert(varchar(10),@parent_ikey)

declare @new_parentkey int
declare @new_ikey int
select @new_parentkey=parentkey, @new_ikey=parent_ikey from ProjectsOfProjects where childkey=@parentkey and ikey=@parent_ikey

-- **************************************************************
-- RECURSIVE CALL
-- **************************************************************
-- if it is not null, we recurse
exec projectAncestors @parentkey, @new_parentkey, @new_ikey , 0 , @returncode
end

END

And the structure of the ProjectOfProjects table is:

CREATE TABLE [dbo].[ProjectsOfProjects](
[ikey] [int] IDENTITY(1,1) NOT NULL,
[parentkey] [int] NOT NULL,
[childkey] [int] NOT NULL,
[parent_ikey] [int] NULL,
CONSTRAINT [PK_ProjectsOfProjects] PRIMARY KEY CLUSTERED
(
[ikey] ASC
)