在一次头脑风暴会议中,讨论了如何以一种互动的方式可视化项目信息。想法是将信息和QR码打印在传统的纸张上,并与一个互动的平板屏幕结合,这样可能会激发参观者的额外好奇心。
一个应用示例是将屏幕连接到一台计算机上的服务器应用程序。在服务器上,可以放置四部不同的电影。在屏幕下方,放置四个与每部电影相对应的QR码。参观者可以使用他们的手机扫描QR码,并在屏幕上启动相应的电影。
为了实现这一点,服务器端需要一个HTTP网络服务器,它监听HTTP调用并在服务器上本地打开文件或应用程序。服务器然后连接到一个屏幕上,所选择的应用程序/电影/图片/演示文稿就会显示出来。QR码中唯一可以存储并用于此目的的信息是一个URL字符串。因此,HTTP服务器必须能够使用REST架构打开URL字符串中提供的文件。
HTTP还需要由活跃的计算机用户启动。如果将其实现为服务,那么在Windows中通常配置的屏幕连接上将无法显示任何内容。这种方法的优点是QR码可以轻松地被始终可用的手机读取。在展览中,通常希望与系统互动,额外的硬件集成成本昂贵。相反,可以使用参观者的移动设备作为工具。唯一需要购买的就是一台便宜的计算机,并将其连接到一个漂亮的屏幕上。然后,可以让参观者扫描QR码来回答问题、启动电影、启动演示文稿或任何其他内容。
允许打开的文件在代码中定义为一个文件夹。要打开文件夹中的文件,文件名在HTTP REST调用中提供的参数中,例如:
http://Myserver:8080/?file=openme.txt
使用代码:
代码简单且可配置,具体取决于想要如何展示文件。对于电影和PowerPoint,发送参数以扩展媒体到全屏。请参阅特定软件手册,了解如何与软件交互。
要创建一个用于启动应用程序的QR码,可以使用互联网上任何可用的QR码创建器,例如:
http://qrcode.kaywa.com/
对于连接字符串,需要服务器的地址或IP、使用的端口以及要在服务器端显示的文件或主页,即:
http://your-address:your-port/?file=your-file
要启动服务器端应用程序,需要以管理员模式启动exe文件(至少对来说是必要的,以便监听端口)。默认端口是8080,可以通过在代码中更改或通过在快捷方式属性的命令字段中指定端口来更改。例如,创建一个快捷方式并为快捷方式属性指定端口。
为请求设备添加了流式传输视频的支持。这是通过在REST调用中添加参数local=true
来完成的,即:
http://your-address:your-port/?file=your-file&local=true
代码:
主循环基本上启动了一个HttpListener
并回答所有调用,通过调用StartProgram
并使用REST参数中提供的文件来响应“已启动”或如果文件不存在或发生任何异常则抛出异常。
C#
//
Source for videos to play locally on the connected device
private
static
string
httpfilesource =
"
http://desenergy.selfip.org/"
;
private
static
string
filefolder =
"
C:\\Videos\\"
;
private
static
void
Main(string[] args)
{
var
server =
new
HttpListener();
int
port;
if
(args !=
null
&& args.Length >
0
&&
int
.TryParse(args[0],
out
port))
server.Prefixes.Add(
@"
http://*:"
+ port +
"
/"
);
else
server.Prefixes.Add(
@"
接下来是实现StartProgram
函数。
提供给StartProgram
函数的文件默认由服务器执行。Windows文件关联将负责如何执行文件。然而,在此实现中,需要从开始就以全屏方式启动一些文件,例如启动电影、PowerPoint、Word文件和主页。
要实现全屏,应用程序会向实际应用程序本身发送启动参数。发送的参数取决于使用的应用程序,但实际的文档或媒体始终作为参数之一提供。
特殊程序的默认程序在常量字符串中定义。请注意,打开特定程序的字符串因安装而异。如果想设计得更严格,可以访问注册表以获取文件夹。
该方法基本上首先清理文件名,以解决北欧字母的一些问题,然后分析字符串并用正确的应用程序启动它。如果没有默认应用程序用于文件类型,应用程序会尝试自己启动文件。
C#
//
Define Your Paths
private
const
String
Reader =
@"
C:\Program Files (x86)\Adobe\Acrobat 10.0\Acrobat\Acrobat.exe"
;
private
const
String
Explorer =
@"
C:\Program Files (x86)\Internet Explorer\iexplore.exe"
;
private
const
String
PowerPoint =
@"
C:\Program Files (x86)\Microsoft Office\Office14\POWERPNT.EXE"
;
private
const
String
WinWord =
@"
C:\Program Files (x86)\Microsoft Office\Office14\winword.exe"
;
private
const
String
WMPlayer =
@"
C:\Program Files\Windows Media Player\wmplayer.exe"
;
private
static
void
StartProgram(
string
s)
{
string
file =
String
.Copy(s);
if
(file !=
null
{
file = file .Replace(
"
ö"
,
"
ö"
);
file = file.Replace(
"
ä"
,
"
ä"
);
file = file.Replace(
"
Ã¥"
,
"
å"
);
}
string
t;
try
{
t = file.Remove(
0
, file.LastIndexOf(
"
."
, StringComparison.Ordinal));
}
catch
{
t = s;
}
if
(file.StartsWith(
"
http://"
))
{
StartProcess(Explorer,
"
-k "
+
"
\""
+ file +
"
\""
);
}
else{
switch
(t.ToLowerInvariant())
{
case
"
.ppt"
:
case
"
.pptx"
:
StartProcess(PowerPoint,
"
/S "
+
"
\""
+ file +
"
\""
);
break
;
case
"
.doc"
:
case
"
.docx"
:
StartProcess(WinWord,
"
/fullscreen "
+
"
\""
+ file +
"
\""
);
break
;
case
"
.mpg"
:
case
"
.mpeg"
:
case
"
.mp4"
:
case
"
.avi"
:
case
"
.ogg"
:
StartProcess(WMPlayer,
"
\""
+ file +
"
\""
+
"
/fullscreen"
);
break
;
case
"
.pdf"
:
StartProcess(Reader,
"
\""
+ file +
"
\""
);
break
;
default
StartProcess(file,
null
);
break
;
}
}
}
最后一部分关闭前一个进程并启动新进程。前一个进程存储在一个静态字段中,因此可以在启动下一个进程之前关闭它。
C#
private
static
Process _process;
private
static
void
StartProcess(
string
program,
string
argumentfile)
try
{
if
(_process !=
null
_process.CloseMainWindow();
}
catch
(Exception)
{
}
_process =
new
Process
{
StartInfo =
{
FileName = program,
Arguments = argumentfile,
WindowStyle = ProcessWindowStyle.Maximized
}
};
//
Configure the process using the StartInfo properties.
_process.Start();
}