« December 2002 | Main | February 2003 »
Resource files can be made available to an assembly by marking their Build Action property to “Embedded Resource”.
If “license.rtf” is in a subfolder “Resources” of an assembly whose default namespace is “
the following code will recover the resource as a string:
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
string rsrcName = “
System.IO.Stream s = a.GetManifestResourceStream(rsrcName);
System.IO.StreamReader sr = new System.IO.StreamReader(s);
string license = sr.ReadToEnd();
The example code in the documentation builds the resource name from the assembly’s name:
string rsrcName = a.GetName().Name + ".Resources.license.rtf";
This doesn’t seem to work in general, since the assembly name can differ from the default namespace.
Use ILDASM to view the assembly manifest when in doubt about what a resource is being named.
SCM has a –silent switch you can pass it.
230236 BUG: SCM.EXE Command Line Arguments Not Documented in SQL 7.0 Books
http://support.microsoft.com/?id=230236
For Example
scm.exe -Action 1 -Server myserver -Service MSSQLServer –Silent 1
To make a database detachable, the suggested method is set the database option OFFLINE, then detach.
USE master
GO
ALTER DATABASE pubs SET OFFLINE WITH ROLLBACK IMMEDIATE
GO
sp_detach_db pubs
GO
Read about OFFLINE database option, and the ROLLBACK clause:
Setting Database Options
http://msdn.microsoft.com/library/en-us/createdb/cm_8_des_03_6ohf.asp
See the table of internal and equivalent external properties:
Using SQL Server Desktop Engine Merge Modules
http://msdn.microsoft.com/library/en-us/distsql/distsql_8yeq.asp
For more information about these properties and valid arguments:
http://msdn.microsoft.com/library/en-us/distsql/distsql_84xl.asp
A. Use the SETUP.INI in the /settings switch (external property).
Example: D:\MSDE2000\>setup.exe /settings setup.ini D:\MSDE2000\setup.ini /L*v C:\MSDE_setup.log
B. You can pass parameters directly to the .msi package (external property) via the command line or place it in the Property table inside the .msi package (internal property). Passing a public property can be done via the command line such as the REBOOT property above, be sure and use all caps when passing public properties (also discussed in the msi.chm help file). So here is an example command line I could use to pass the REBOOT public property:
Msiexec /i MyPackage.msi REBOOT=ReallySuppress
If you want to ALWAYS have a property set and run, you can open up the .msi package using an authoring tool, such as Orca included in the SDK Tools directory, and enter the Property name and value in the Property table. See http://support.microsoft.com/support/kb/articles/q255/9/05.asp for information on using Orca to make this type change.
C. You can run Setup.exe from within another Microsoft® Windows® application through a call to the Win32® CreateProcess() function, passing setup switches in a character string using the lpCommandLine parameter.
D. To run other apps from a merge modules, like SCM.exe to start SQL Server, you have to design custom actions and pass parameters, which I know is not easy with Windows Installer.
See also
Desktop Engine Installation Samples
http://msdn.microsoft.com/library/en-us/distsql/distsql_7b91.asp
Adding additional dialog boxes to installer interface:
- Give the properties uppercase names.
Adding custom actions:
- Define a class that derives from System.Configuration.Install.Installer. Easiest way to do this is to use the “Installer Class” template when adding an new item.
- Add the [RunInstaller(true)] attribute to the class.
- Override Install():
public override void Install(System.Collections.IDictionary stateSaver) {
base.Install(stateSaver);
string nonsense = Context.Parameters["nonsense"];
// File appears in c:\Windows\System32
StreamWriter sw = File.CreateText("myinstalltest.txt");
sw.WriteLine(nonsense);
sw.Close();
}
- Add a custom action to the installer:
o Add the action to the root for all four phases, or just to the phase of interest (typically install).
o Add CustomActionData entries for parameters to be passed to the Installer override:
/nonsense="[NONSENSETEXT]"
To run another msi as a custom action from within an msi look here. It isn’t directly supported by a .NET setup project.
The default Context.Parameters collection contains information like the following:
Parameters["nonsense"]="Default Nons4ense"
Parameters["logfile"]=""
Parameters["installtype"]="notransaction"
Parameters["action"]="install"
Parameters["assemblypath"]="c:\program files\jobquake\jobquake.exe"
The AfterInstall event doesn’t fire as part running “Install” from the IDE, and
the Commit override doesn’t get called.
Windows Installer Documentation
dotnetfx documentation Can download self extracting dotnetfxredist.exe from here.
InstMsiA.Exe – Windows Installer Installer
InstMsiW.Exe – Windows Installer Installer
Setup.exe – Bootstrap, verifies Windows Installer, then installs .msi.
Setup.msi – The actual application.
Msiexec.exe Installs .msi files. Takes command line options to modify installer’s behavior.
Public installer properties can be changed at the command line or “transformed” within the .msi file(?)
Required Public Properties:
The ProductCode property is a unique identifier for the particular product release, represented as a string GUID, for example "{12345678-1234-1234-1234-123456789012}". Letters used in this GUID must be uppercase. This ID must vary for different versions and languages.
A product upgrade that updates a product into an entirely new product must also change the product code. The 32-bit and 64-bit versions of an application's package must be assigned different product codes.
The ProductCode is advertised as a product property, and is the primary method of specifying the product. This property is REQUIRED.
The value of the ProductVersion property is the version of the product in string format. This property is REQUIRED.
The format of the string is as follows: major.minor.build
The first field is the major version and has a maximum value of 255. The second field is the minor version and has a maximum value of 255. The third field is called the build version or the update version and has a maximum value of 65,535.
At least one of the three fields of ProductVersion must change for an upgrade using the Upgrade table. Any update that changes only the package code, but leaves ProductVersion and ProductCode unchanged is called a small update. The three versions fields are provided primarily for convenience. For example, if you want to change ProductVersion, but don't want to change either the major or minor versions, you can change the build version.
Note that Windows Installer uses only the first three fields of the product version. If you include a fourth field in your product version, the installer ignores the fourth field.
|
Extension |
Description |
|
.msi |
Windows Installer Database. |
|
.msm |
Windows Installer Merge Module. |
|
.msp |
Windows Installer Patch. |
|
.mst |
Windows Installer Transform. |
|
.idt |
Exported Windows Installer Database Table. |
|
.cub |
Validation module. |
|
.pcp |
Windows Installer Patch Creation File |
Repeated captures are accessed through Groups[i].Captures[j].
Using non-capturing groups (?:) simplifies access by eliminating unused groups from the results.
Match m = Regex.Match(uri, @"(?'url'[^\?]+)(?:\?(?:(?'arg'[^=&]+)=(?'value'[^&]+)&?)*)?");
StringBuilder sb = new StringBuilder();
sb.Append("<html><body ><form id='f' method='post' action='");
sb.Append(m.Groups["url"].Value);
sb.Append("'>\n");
for (int i=0; i < m.Groups["arg"].Captures.Count; i++)
sb.AppendFormat("<input type='string' name='{0}' value='{1}'>\n"
, m.Groups["arg"].Captures[i].Value
, System.Web.HttpUtility.UrlDecode(m.Groups["value"].Captures[i].Value));
sb.Append("<input type='submit' name='Do' value='It'></form></body></html>");
The following example triggers a client side HTTP redirect:
string html = String.Format(@"<META HTTP-EQUIV='REFRESH' CONTENT='0; URL={0}'>", uri);
Not sure if these comments reflect reality or just the way things should be. Generally found the behavior very confusing, under documented, and most likely improperly implemented.
So I ended up writing my own menu merging functions.
MergeType as MenuMerge property of a MenuItem:
Add – The item will be added in a merge. Items appear in order, after existing items of the same or higher order.
Remove – The item is ignored in a merge.
Replace – Each replace item will appear after the Add/Remove items with equal order and replace the first Replace item with equal order.
MergeItems – The submenu items of the item are merged.
MergeOrder as int, zero based
Can’t use a MenuItem in more than one menu – use CloneMenu.
Menu.MergeMenu(Menu) – The order of the menu doesn’t matter. The order of the menuItems does.
Closing and disposing SqlConnection objects isn’t sufficient to guarantee that you’ll be able to sp_detach_db a database your done working with. A trick that seems to work is to preceed calls to Close() with a call to ChangeDatabase(“master”).
Use exec sp_who & sp_lock with QueryAnalyzer to monitor the locks as you step through the program.
HOW TO: Manage the SQL Server Desktop Engine (MSDE 2000) by Using the Osql Utility
C:\>osql -?
usage: osql [-U login id] [-P password]
[-S server] [-H hostname] [-E trusted connection]
[-d use database name] [-l login timeout] [-t query timeout]
[-h headers] [-s colseparator] [-w columnwidth]
[-a packetsize] [-e echo input] [-I Enable Quoted Identifiers]
[-L list servers] [-c cmdend] [-D ODBC DSN name]
[-q "cmdline query"] [-Q "cmdline query" and exit]
[-n remove numbering] [-m errorlevel]
[-r msgs to stderr] [-V severitylevel]
[-i inputfile] [-o outputfile]
[-p print statistics] [-b On error batch abort]
C:\>osql –Q -S (local)\JobQuake -U sa -P
C:\>osql –Q -S (local)\JobQuake -E
C:\>osql -S (local)\JobQuake -U sa -P
exec sp_password null, 'bojekauq', 'sa'
create database JobSearch on (NAME='js_data', FILENAME='c:\js.mdf', SIZE=1, FILEGROWTH=10%)
create database JobSearch on (NAME='js_data', FILENAME='c:\js.mdf', SIZE=1, FILEGROWTH=10%) COLLATE SQL_Latin1_General_CP1_CI_AS
Creates the file c:\js_log.LDF as the log file.
backup database JobSearch TO DISK='c:\js.bak'
restore database JobSearch from disk='c:\js.bak'
exec sp_detach_db 'JobSearch'
exec sp_attach_single_file_db 'JobSearch', 'c:\js.mdf'
C:\>osql -L
Servers:
(local)
BLASTER
KIRA\JOBQUAKE
OSIRIS\VSdotNET
PELL
PELL\JOBQUAKE
PELL\VSdotNET
Visual Studio .NET 2003 does not include Microsoft SQL Server Desktop Engine (MSDE). To download MSDE, go to http://go.microsoft.com/fwlink/?linkid=13962.
Setup.exe /qb+ INSTANCENAME=VSDOTNET DISABLENETWORKPROTOCOLS=1 SAPWD=<YOUR SA PASSWORD>
Modified the setup.ini file for a vanilla VSDOTNET install, zipped and put on web site as msde.exe.
Tested on KIRA (Windows XP) works. Unzips to an odd folder that you have to go track down…
Tested on Virtual PC Windows 98. Works. Install has some warts.
Copied from MSDN’s “Installing MSDE”:
During setup, you can choose to copy the installation files for MSDE to your computer; this gives you the option of manually installing MSDE at a later time.
Installing MSDE involves three steps:
You can skip the following procedure if you intend to use the default instance name, "VsdotNet2003".
To create a custom MSDE instance name
c:\Program Files\Microsoft Visual Studio .NET 2003\Setup\MSDE\ and then click OK. setup.ini to edit the file in Notepad. VSdotNET2003 in INSTANCENAME=VSdotNET with the instance name of your choice. You can install MSDE simply by running the appropriate setup file from the location where Setup copied the file.
To install MSDE
c:\Program Files\Microsoft Visual Studio .NET 2003\Setup\MSDE\ and click OK. setup.exe. After you have installed MSDE, you must then start the MSDE service.
To start the MSDE service
NET START MSSQL$<instance name> and click OK. For example, if you chose to use the default instance name, you would enter NET START MSSQL$VSdotNET2003.
After upgrading to the MSDE SP3 .msm files:
1. These changes are still need.
After building a MSDE installer (.msi), you must edit the file with orca.exe (right click menu) to make the following changes:
InstallExecuteSequence table: 104->105,103->104,205->103,1525->6601
InstallUISequence table: 104->105,103->104,205->103
Property table:
Add Row SqlInstanceName = JobQuake
Add Row SqlProgramDir = c:\Program Files\JobQuake\
Add Row SqlSaPwd = KzSqlMsde
2. Don’t add these changes.
// Add Row SqlSecurityMode = SQL
// Add Row SqlDataDir = c:\Program Files\JobQuake Database\Data
Deploying .NET Applications: Lifecycle Guide
dotnetfx.exe requires
HOW TO: Obtain and Install SQL Server 2000 Desktop Engine (MSDE 2000) (includes requirements)
HOW TO: Connect to Microsoft Desktop Engine (for 98, must use SQL. sa initially blank)
Choosing and Using MSDE 2000 as the Database Engine for Your Application (links to using OSQL & backups using T-SQL)
Embedding MSDE 2000 Setup into the Setup of Custom Applications
Cannot Specify Instance Name Using SQL Server 2000 Merge Modules
HOW TO: Author MSDE 2000 Setup Packages by Using Visual Studio .NET
Run Setup.exe with /L*v [filename] for installation details logging. (*v is verbose logging, 10x the size. Try just /L first.)
HOWTO: Use the Orca Database Editor to Edit Windows Installer Files
This downloaded the Installer SDK 1.2 into c:\Program Files\MsiIntel.SDK, then ran the orca.msi in the tools directory.
To avoid 126 problem, modified the InstallExecuteSequence sequence numbers: 104->105, GetSqlState 103->104, StreamSupportFiles 206->103.
Didn’t see anything to fix in InstallUISequence.
Got new MSM files…..now the Setup project builds cleanly and the dependencies prior to the 1033 folder are complete. But it still fails….looks like the 126 bug.
InstallExecuteSequence InstallUISequence
GetSqlState 103 103
StreamSupportFiles 205 205
104->105, 103->104, 205->103
Now it complains about an invalid instance name…. so let’s try using Orca to add the guys below:
SqlInstanceName = JQ
Man it was looking so good! Then error code 2613….. turn on logging and look it up.
Called Dwayne Lanclos @ SQL Server Support…469-775-8400 he had an other persons case notes which said:
InstallExecuteSequence: Move RemoveExistingProducts (1525->6601) after InstallFinalize (6600) Note that this doubles up 6601, but it seems okay.
Putting the external properties below under an [Options] section in a Setup.ini file works when running setup.exe and also via Orca as internal property table entries.
It appends MSSQL$[SqlInstanceName] to the paths specified for SqlDataDir and SqlProgramDir.
The setup author could add an entry to the Property table by using a Windows Installer database editing tool such as Orca.exe to assign the specific internal properties used in the SQL Server 2000 MSDE merge modules to a specific value. For example, to set the instance name to be used, you would add an entry to the Property table and assign the SqlInstanceName property a specific value.
The following internal properties are used by the SQL Server 2000 MSDE merge modules and can be set in this manner. The corresponding external properties are listed for reference; however, they are available only in the SQL Server 2000 Desktop Engine install package, not the SQL Server 2000 MSDE merge modules.
External Property Internal Property
CALLBACK SqlCallback
COLLATION SqlCollation
DATADIR SqlDataDir [TargetDir]\Data
TARGETDIR SqlProgramDir [TargetDir]\Sql
INSTANCENAME SqlInstanceName JobQuake
SECURITYMODE SqlSecurityMode Sql
UPGRADE SqlUpgrade
UPGRADEUSER SqlUpgradeUser
Some of the above properties must be specific values. The value of SECURITYMODE or SqlSecurityMode should be SQL in order to allow SQL Server authentication. For upgrading, UPGRADE or SqlUpgrade should be 1, and UPGRADEUSER or SqlUpgradeUser should be SA.
STATUS
This behavior is by design.
REFERENCES
255905 HOWTO: Use Orca to Edit Windows Installer Files
Succeeded by modifying machine.config to change account from machine (ASPNET) to SYSTEM.
Problem is special permission is needed to create a new category key in the HKLM hive.
For more info see: http://www.gotdotnet.com/team/upgrade/v1/aspnet_account_readme.doc
Restarting IIS might be necessary after modifying machine.config.
Switching back to the “machine” account after adding entries as “SYSTEM” works. The category key exists? And now it just stopped working! So back to system on PELL. Yam has never had a problem…
Here's a little code snippet that hashes the plain-text customer password for storage in a database table:
sqlConnection.Open();
SqlCommand cmd = sqlCmdCustomerAdd;
cmd.Parameters["@guid"].Value = Guid.NewGuid();
cmd.Parameters["@email"].Value = tbEmail.Text;
byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(tbPassword.Text);
byte[] passwordHash = ((HashAlgorithm) CryptoConfig.CreateFromName("MD5")).ComputeHash(passwordBytes);
cmd.Parameters["@password"].Value = Convert.ToBase64String(passwordHash);
cmd.ExecuteNonQuery();
sqlConnection.Close();