在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
在Window窗体程序开发的时候,如果使用多线程编程,在子线程中访问主线程窗体内的控件,就需要使用控件的Control.Invoke方法或者BeginInvoke方法。但是有时候因为Window执行速度太快,尤其是你写代码的时候在InitializeComponent();完成之前起了一个线程去执行某些操作,涉及到窗体控件的,当你在调用
Control.Invoke的时候,就可能出现 “在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke”错误。
解决的办法就是让线程等待,直到窗口句柄创建完毕:
//防止在窗口句柄初始化之前就走到下面的代码
while (!this.IsHandleCreated)
{
;
}
this.Invoke(new MethodWithoutParameter(LoadContactTemplate));
XP系统创建了一个新管理员账户后,原来的Administrator账户不见了,怎样恢复Administrator账户?
安装Windows XP时,如果设置了一个管理员账户,那么系统内置没有密码保护的Administrator管理员账户是不会出现在用户登录列表中的。虽然它身在幕后,可却拥有系统最高权限,为了方便操作及保证系统安全,可以先给它设置密码,然后再把它请到台前来。以下便介绍具体方法。
1.使用“传统登录提示”登录 启动系统到欢迎屏幕时,按两次“Ctrl+Alt+Delete”组合键,在出现的登录框中输入Administrator账户的用户名和密码即可。也可以单击“开始→控制面板”,双击“用户账号”图标,在弹出的“用户账号”窗口中,单击“更改用户登录或注销的方式”,去掉“使用欢迎屏幕”前的复选框,单击“应用选项”即可在启动时直接输入Administrator账户名及密码登录。
2.在登录的欢迎屏幕显示Administrator账户 单击“开始→运行”,输入regedit后回车,打开注册表编辑器,依次展开“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList”分支,这下面建个dword值,名字为你的帐户名(administrator),将右边的Administrator的值改为1,即可让Administrator账户出现在登录的欢迎屏幕上。
3.自动登录到Administrator账户 单击“开始→运行”,输入control userpasswords2后回车,在打开的“用户账户”窗口去掉“要使用本机,用户必须输入密码”前的复选框,按“应用”后,在弹出的“自动登录”窗口中输入Administrator账户密码(如图1),按两次“确定”即可。注意:如果原来就设置了其它账户自动登录,应该先选中“要使用本机,用户必须输入密码”前的复选框,按“应用”后再去掉选中的复选框。也可以修改注册表实现自动登录,不过没有以上方法方便。 当然,如果不需要Administrator账户,可以依次打开“开始→控制面板→管理工具→计算机管理”,在“计算机管理”窗口,展开“系统工具→本地用户和组→用户”,在“用户”右边窗口双击Administrator账户,在弹出的“属性”窗口中选中“账号已停用”前的复选框,按“确定”即可停用Administrator账户。
c#服务程序允许服务与桌面交互
我们写一个服务,有时候要让服务启动某个应用程序,就要修改服务的属性,勾选允许服务与桌面交互,
可以用修改注册表实现,我们必须在安装后操作,所以请重写Installer的OnAfterInstall。
private void SetServiceDesktopInsteract(string serviceName) {
ManagementObject wmiService = new ManagementObject(string.Format("Win32_Service.Name='{0}'",serviceName));
ManagementBaseObject changeMethod = wmiService.GetMethodParameters("Change");
changeMethod["DesktopInteract"] = true;
ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", changeMethod, null);
}
将此方法放入onAfterInstall即可
也可通过修改注册表实现,但是需要重启才能生效:
RegistryKey rk = Registry.LocalMachine;
string key = @"SYSTEM\CurrentControlSet\Services\" + this.sInstaller.ServiceName;
RegistryKey sub = rk.OpenSubKey(key, true);
int value = (int)sub.GetValue("Type");
if (value < 256) {
sub.SetValue("Type", value | 256);
}
base.OnAfterInstall(savedState);
}
C#中执行bat文件或者cmd文件
1、执行批处理文件
System.Diagnostics.Process.Start(path);
path为文件路径
这个也可以用作执行exe文件.
2、修改批处理文件
FileStream aFile = new FileStream(filePath, FileMode.OpenOrCreate);
temp = ""; //批处理文件中的内容
charData = temp.ToCharArray();
Encoder e = Encoding.UTF8.GetEncoder();
e.GetBytes(charData, 0, charData.Length, byData, 0, true); //字符型数组转换成字节型数组
aFile.Write(byData, 0, byData.Length);
aFile.Close();
3.想把bat运行时候的信息在C#文本框中显示:
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "bat文件|*.bat|cmd文件|*.cmd";
if (dlg.ShowDialog() == DialogResult.OK)
{
StreamReader sr = File.OpenText(dlg.FileName);
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
while (sr.Peek() != -1)
{
string line = sr.ReadLine();
p.StandardInput.WriteLine(line);
}
sr.Close();
p.StandardInput.WriteLine("exit");
string response = p.StandardOutput.ReadToEnd();
string[] strLines = response.Split(new char[] { '/r', '/n' });
for (int i = 8; i < strLines.Length-6; i++)
{
textBox1.AppendText(string.Format("{0}/r/n", strLines[i]));
}
p.Close();
}
如果你执行方法的时间比较长。可以修改为这个
C# code
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "bat文件|*.bat|cmd文件|*.cmd";
if (dlg.ShowDialog() == DialogResult.OK)
{
StreamReader sr = File.OpenText(dlg.FileName);
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
while (sr.Peek() != -1)
{
string line = sr.ReadLine();
p.StandardInput.WriteLine(line);
}
sr.Close();
p.StandardInput.WriteLine("exit");
p.WaitForExit();
string response = p.StandardOutput.ReadToEnd();
string[] strLines = response.Split(new char[] { '/r', '/n' });
for (int i = 8; i < strLines.Length - 6; i++)
{
textBox1.AppendText(string.Format("{0}/r/n", strLines[i]));
}
p.Close();
}
DOS命令如何获取当前文件路径
set pa=%cd%将当前路径赋值给pa
echo %pa%显示pa变量
C#写的WINDOWS服务程序
服务程序在C#中的写法。
1.在VS中新建一个WINDOWS服务程序的项目WinSrv_A。
2.更改SERVICE1.CS属性SERVICENAME为你所要建立的服务名称,在服务管理器->名称中你可以看到你的服务名
3.按F7进入代码窗口,里面有2个重载函数是你要在其中写代码
/// <summary>
/// 停止此服务。
/// </summary>
protected override void OnStart(string[] args)
{
// TODO: 在此处添加代码以启动服务。
String s = System.DateTime.Now.ToString();
if(!File.Exists("c:\\srvlog.txt"))
{
StreamWriter sr = File.CreateText("c:\\bbbirdlog.txt");
sr.WriteLine("-------------------------START SRV---------------------");
sr.WriteLine ("我的新服务在{0}时间开始",s);
sr.WriteLine ("我可以写整型 {0} or 浮点型 {1},等等.",1, 4.2);
sr.Close();
}
else
{
StreamWriter sr = File.AppendText("c:\\bbbirdlog.txt");
sr.WriteLine("-------------------------START SRV---------------------");
sr.WriteLine ("我的新服务在{0}时间开始",s);
sr.WriteLine ("我可以写整型 {0} or 浮点型 {1},等等.",1, 4.2);
sr.Close();
}
}
/// <summary>
/// 停止此服务。
/// </summary>
protected override void OnStop()
{
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
String s1 = System.DateTime.Now.ToString();
if(!File.Exists("c:\\srvlog.txt"))
{
StreamWriter sr = File.CreateText("c:\\bbbirdlog.txt");
sr.WriteLine("-------------------------STOP SRV---------------------");
sr.WriteLine ("我的新服务在{0}时间停止",s1);
sr.Close();
}
else
{
StreamWriter sr = File.AppendText("c:\\bbbirdlog.txt");
sr.WriteLine("-------------------------STOP SRV---------------------");
sr.WriteLine ("我的新服务在{0}时间停止",s1);
sr.Close();
}
}
4.回到设计窗口点右键选择添加安装程序生成serviceInstaller1 serviceProcessInstaller1两个组件把serviceInstaller1的属性ServiceName改写为你的服务名,并把启动模式设置为AUTOMATIC,把serviceProcessInstaller1的属性account改写为LocalSystem
5.编译链接生成服务程序。
6.用.net framework工具installutil安装服务程序即可
首先要找到InstallUtil.exe所在的文件夹,一般在C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319文件夹下,后面是.net的版本号码
然后在命令行中执行 InstallUtil.exe WindowsService1.exe就可以了,WindowsService1.exe是你编译好的文件。
然后在“服务”中启动该服务,或者在“运行”中输入“NET START Service1”
或者把以下命令写入.cmd文件,双击执行
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil D:\WindowsService1\WindowsService1\bin\Debug\WindowsService1.exe
NET START Service1
7.卸载服务时,首先在“服务”中停止服务,或者在命令行输入“NET STOP Service1”停止服务,然后执行命令“InstallUtil.exe -u Wsv_A.exe”,卸载该服务。
以下命令写入.cmd文件:
NET STOP Service1
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil /u D:\WindowsService1\WindowsService1\bin\Debug\WindowsService1.exe
或者:
NET STOP Service1
%Windir%\Microsoft.NET\Framework\v4.0.30319\installutil /u %cd%\Service1.exe
%Windir%\Microsoft.NET\Framework\v4.0.30319\installutil %cd%\Service1.exe
NET START Service1
注意:服务程序中经常会用到Timer控件,工具箱中的Timer控件可能是 System.Windows.Forms命名空间下的,这个不能用,一定要找到System.Timers控件,如果工具箱里面没有的话,可以在工具箱上点击鼠标右键,选择添加项,从.net Framework组件中选择System.Timers.
C# 启动和结束进程
启动进程
private void StartProcess()
{
try
{
if (!CheckProcessExists())
{
Process p = new Process();
p.StartInfo.FileName = System.IO.Path.Combine(Application.StartupPath, "DataTool.exe");
p.StartInfo.Arguments = "DataTool.exe";
p.StartInfo.UseShellExecute = true;
p.Start();
p.WaitForInputIdle(10000);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Source + " " + ex.Message);
}
}
private bool CheckProcessExists()
{
Process[] processes = Process.GetProcessesByName("DataTool");
foreach (Process p in processes)
{
if (System.IO.Path.Combine(Application.StartupPath, "DataTool.exe") == p.MainModule.FileName)
return true;
}
return false;
}
结束进程:
private void KillProcessExists()
{
Process[] processes = Process.GetProcessesByName("AppStart");
foreach (Process p in processes)
{
if (System.IO.Path.Combine(Application.StartupPath, "AppStart.exe") == p.MainModule.FileName)
{
p.Kill();
p.Close();
}
}
}
卸载 Appdomain 时出错。(异常来自 HRESULT:0x80131015)终极解决办法
程序关闭的时候总是出现错误:
卸载 Appdomain 时出错。 (异常来自 HRESULT:0x80131015)
网上查了资料都说是 .net 4.0 关于 reportviewer的bug,卸载线程出错。不管是不是bug问题总要解决的:
只要在窗口的关闭事件中,调用ReportViewer控件的LocalReport.Dispose()方法即可!
就像这样:
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
reportViewer1.LocalReport.Dispose();
this.Dispose();
}
Sqlserver查询数据库文件大小和剩余空间
在MS Sql Server中可以能过以下的方法查询出磁盘空间的使用情况及各数据库数据文件及日志文件的大小及使用利用率:
1、查询各个磁盘分区的剩余空间:
Exec master.dbo.xp_fixeddrives
2、查询数据库的数据文件及日志文件的相关信息(包括文件组、当前文件大小、文件最大值、文件增长设置、文件逻辑名、文件路径等)
select * from [数据库名].[dbo].[sysfiles]
转换文件大小单位为MB:
select name, convert(float,size) * (8192.0/1024.0)/1024. from [数据库名].dbo.sysfiles
3、查询当前数据库的磁盘使用情况:
Exec sp_spaceused
4、查询数据库服务器各数据库日志文件的大小及利用率
DBCC SQLPERF(LOGSPACE)
SQL SERVER 收缩数据库命令
--备份数据库
BACKUP DATABASE testdb TO DISK='d:\data\testdb20070906.bak'
--清空日志
DUMP TRANSACTION testdb WITH NO_LOG
--截断事务日志
BACKUP LOG testdb WITH NO_LOG
--收缩数据库
DBCC SHRINKDATABASE(testdb)
--设置自动收缩
EXEC SP_DBOPTION testdb,AUTOSHRINK,TRUE
特别注意:
请按步骤进行,未进行前面的步骤,请不要做后面的步骤
否则可能损坏你的数据库.
一般不建议做第4,6两步
第4步不安全,有可能损坏数据库或丢失数据
第6步如果日志达到上限,则以后的数据库处理会失败,在清理日志后才能恢复.
1.清空日志
DUMP TRANSACTION 库名 WITH NO_LOG
2.截断事务日志
BACKUP LOG 数据库名 WITH NO_LOG
3.收缩数据库文件(如果不压缩,数据库的文件不会减小)
企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件
·选择日志文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了
·选择数据文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了,
·收缩数据库,也可以用SQL语句来完成
DBCC SHRINKDATABASE(客户资料)
·收缩指定数据文件,1是文件号,可以通过这个语句查询到:
select * from sysfiles
DBCC SHRINKFILE(1)
4.为了最大化的缩小日志文件(如果是sql 7.0,这步只能在查询分析器中进行)
a.分离数据库:
企业管理器--服务器--数据库--右键--分离数据库
b.在我的电脑中删除LOG文件
c.附加数据库:
企业管理器--服务器--数据库--右键--附加数据库
此法将生成新的LOG,大小只有500多K
或用代码:
下面的示例分离 pubs,然后将 pubs 中的一个文件附加到当前服务器。
a.分离
EXEC sp_detach_db @dbname = 'pubs'
b.删除日志文件
c.再附加数据库文件
EXEC sp_attach_single_file_db @dbname = 'pubs',
@physname = 'c:\Program Files\Microsoft
SQL Server\MSSQL\Data\pubs.mdf'
5.为了以后能自动收缩,做如下设置
企业管理器--服务器--右键数据库--属性--选项--选择"自动收缩"
SQL语句设置方式:
EXEC sp_dboption '数据库名',
'autoshrink', 'TRUE'
6.如果想以后不让它日志增长得太大
企业管理器--服务器--右键数据库--属性--事务日志
将文件增长限制为xM(x是你允许的最大数据文件大小)
SQL语句的设置方式:
alter database 数据库名 modify file(name=逻辑文件名,maxsize=20)